blob: 2c683e902c97a3a66160d81d689e4fdbc61b6120 [file] [log] [blame]
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001// Copyright 2011 Google Inc. All Rights Reserved.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07003#include "class_linker.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07004
Brian Carlstromdbc05252011-09-09 01:59:59 -07005#include <deque>
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07006#include <string>
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07007#include <utility>
Elliott Hughes90a33692011-08-30 13:27:07 -07008#include <vector>
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07009
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070010#include "casts.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070011#include "class_loader.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070012#include "dex_cache.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070013#include "dex_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070014#include "dex_verifier.h"
15#include "heap.h"
Elliott Hughescf4c6c42011-09-01 15:16:42 -070016#include "intern_table.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "logging.h"
Elliott Hughes54e7df12011-09-16 11:47:04 -070018#include "monitor.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070019#include "object.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070020#include "runtime.h"
Brian Carlstroma663ea52011-08-19 23:33:41 -070021#include "space.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070022#include "thread.h"
Elliott Hughes54e7df12011-09-16 11:47:04 -070023#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070024#include "utils.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070025
26namespace art {
27
Elliott Hughes4a2b4172011-09-20 17:08:25 -070028namespace {
29
30void ThrowNoClassDefFoundError(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
31void ThrowNoClassDefFoundError(const char* fmt, ...) {
32 va_list args;
33 va_start(args, fmt);
34 Thread::Current()->ThrowNewExceptionV("Ljava/lang/NoClassDefFoundError;", fmt, args);
35 va_end(args);
36}
37
Elliott Hughese555dc02011-09-25 10:46:35 -070038void ThrowClassFormatError(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
39void ThrowClassFormatError(const char* fmt, ...) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -070040 va_list args;
41 va_start(args, fmt);
Elliott Hughese555dc02011-09-25 10:46:35 -070042 Thread::Current()->ThrowNewExceptionV("Ljava/lang/ClassFormatError;", fmt, args);
Elliott Hughes4a2b4172011-09-20 17:08:25 -070043 va_end(args);
44}
45
46void ThrowLinkageError(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
47void ThrowLinkageError(const char* fmt, ...) {
48 va_list args;
49 va_start(args, fmt);
50 Thread::Current()->ThrowNewExceptionV("Ljava/lang/LinkageError;", fmt, args);
51 va_end(args);
52}
53
54void ThrowEarlierClassFailure(Class* c) {
55 /*
56 * The class failed to initialize on a previous attempt, so we want to throw
57 * a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we
58 * failed in verification, in which case v2 5.4.1 says we need to re-throw
59 * the previous error.
60 */
61 LOG(INFO) << "Rejecting re-init on previously-failed class " << PrettyClass(c);
62
63 if (c->GetVerifyErrorClass() != NULL) {
64 // TODO: change the verifier to store an _instance_, with a useful detail message?
65 std::string error_descriptor(c->GetVerifyErrorClass()->GetDescriptor()->ToModifiedUtf8());
66 Thread::Current()->ThrowNewException(error_descriptor.c_str(), "%s",
67 PrettyDescriptor(c->GetDescriptor()).c_str());
68 } else {
69 ThrowNoClassDefFoundError("%s", PrettyDescriptor(c->GetDescriptor()).c_str());
70 }
71}
72
73}
74
Elliott Hughes418d20f2011-09-22 14:00:39 -070075const char* ClassLinker::class_roots_descriptors_[] = {
Brian Carlstroma663ea52011-08-19 23:33:41 -070076 "Ljava/lang/Class;",
77 "Ljava/lang/Object;",
Elliott Hughes418d20f2011-09-22 14:00:39 -070078 "[Ljava/lang/Class;",
Brian Carlstroma663ea52011-08-19 23:33:41 -070079 "[Ljava/lang/Object;",
80 "Ljava/lang/String;",
Elliott Hughes80609252011-09-23 17:24:51 -070081 "Ljava/lang/reflect/Constructor;",
Brian Carlstroma663ea52011-08-19 23:33:41 -070082 "Ljava/lang/reflect/Field;",
83 "Ljava/lang/reflect/Method;",
84 "Ljava/lang/ClassLoader;",
85 "Ldalvik/system/BaseDexClassLoader;",
86 "Ldalvik/system/PathClassLoader;",
Shih-wei Liao55df06b2011-08-26 14:39:27 -070087 "Ljava/lang/StackTraceElement;",
Brian Carlstroma663ea52011-08-19 23:33:41 -070088 "Z",
89 "B",
90 "C",
91 "D",
92 "F",
93 "I",
94 "J",
95 "S",
96 "V",
97 "[Z",
98 "[B",
99 "[C",
100 "[D",
101 "[F",
102 "[I",
103 "[J",
104 "[S",
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700105 "[Ljava/lang/StackTraceElement;",
Brian Carlstroma663ea52011-08-19 23:33:41 -0700106};
107
Elliott Hughes5f791332011-09-15 17:45:30 -0700108class ObjectLock {
109 public:
110 explicit ObjectLock(Object* object) : self_(Thread::Current()), obj_(object) {
111 CHECK(object != NULL);
112 obj_->MonitorEnter(self_);
113 }
114
115 ~ObjectLock() {
116 obj_->MonitorExit(self_);
117 }
118
119 void Wait() {
120 return Monitor::Wait(self_, obj_, 0, 0, false);
121 }
122
123 void Notify() {
124 obj_->Notify();
125 }
126
127 void NotifyAll() {
128 obj_->NotifyAll();
129 }
130
131 private:
132 Thread* self_;
133 Object* obj_;
134 DISALLOW_COPY_AND_ASSIGN(ObjectLock);
135};
136
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700137ClassLinker* ClassLinker::Create(const std::vector<const DexFile*>& boot_class_path,
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700138 const std::vector<const DexFile*>& class_path,
Brian Carlstromc74255f2011-09-11 22:47:39 -0700139 InternTable* intern_table, bool image) {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700140 CHECK_NE(boot_class_path.size(), 0U);
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700141 UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700142 if (image) {
143 class_linker->InitFromImage(boot_class_path, class_path);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700144 } else {
Brian Carlstromc74255f2011-09-11 22:47:39 -0700145 class_linker->Init(boot_class_path, class_path);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700146 }
Carl Shapiro61e019d2011-07-14 16:53:09 -0700147 // TODO: check for failure during initialization
148 return class_linker.release();
149}
150
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700151ClassLinker::ClassLinker(InternTable* intern_table)
Brian Carlstrom16192862011-09-12 17:50:06 -0700152 : lock_("ClassLinker lock"),
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700153 class_roots_(NULL),
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700154 array_interfaces_(NULL),
155 array_iftable_(NULL),
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700156 init_done_(false),
157 intern_table_(intern_table) {
Elliott Hughes418d20f2011-09-22 14:00:39 -0700158 CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700159}
Brian Carlstroma663ea52011-08-19 23:33:41 -0700160
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700161void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path,
162 const std::vector<const DexFile*>& class_path) {
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700163 CHECK(!init_done_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700164
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700165 // java_lang_Class comes first, its needed for AllocClass
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700166 Class* java_lang_Class = down_cast<Class*>(
167 Heap::AllocObject(NULL, sizeof(ClassClass)));
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700168 CHECK(java_lang_Class != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700169 java_lang_Class->SetClass(java_lang_Class);
170 java_lang_Class->SetClassSize(sizeof(ClassClass));
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700171 // AllocClass(Class*) can now be used
Brian Carlstroma0808032011-07-18 00:39:23 -0700172
Elliott Hughes418d20f2011-09-22 14:00:39 -0700173 // Class[] is used for reflection support.
174 Class* class_array_class = AllocClass(java_lang_Class, sizeof(Class));
175 class_array_class->SetComponentType(java_lang_Class);
176
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700177 // java_lang_Object comes next so that object_array_class can be created
Brian Carlstrom4873d462011-08-21 15:23:39 -0700178 Class* java_lang_Object = AllocClass(java_lang_Class, sizeof(Class));
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700179 CHECK(java_lang_Object != NULL);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700180 // backfill Object as the super class of Class
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700181 java_lang_Class->SetSuperClass(java_lang_Object);
182 java_lang_Object->SetStatus(Class::kStatusLoaded);
Brian Carlstroma0808032011-07-18 00:39:23 -0700183
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700184 // Object[] next to hold class roots
Brian Carlstrom4873d462011-08-21 15:23:39 -0700185 Class* object_array_class = AllocClass(java_lang_Class, sizeof(Class));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700186 object_array_class->SetComponentType(java_lang_Object);
Brian Carlstroma0808032011-07-18 00:39:23 -0700187
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700188 // Setup the char class to be used for char[]
189 Class* char_class = AllocClass(java_lang_Class, sizeof(Class));
190
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700191 // Setup the char[] class to be used for String
Brian Carlstrom4873d462011-08-21 15:23:39 -0700192 Class* char_array_class = AllocClass(java_lang_Class, sizeof(Class));
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700193 char_array_class->SetComponentType(char_class);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700194 CharArray::SetArrayClass(char_array_class);
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700195
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700196 // Setup String
197 Class* java_lang_String = AllocClass(java_lang_Class, sizeof(StringClass));
198 String::SetClass(java_lang_String);
199 java_lang_String->SetObjectSize(sizeof(String));
200 java_lang_String->SetStatus(Class::kStatusResolved);
Jesse Wilson14150742011-07-29 19:04:44 -0400201
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700202 // Backfill Class descriptors missing until this point
Brian Carlstromc74255f2011-09-11 22:47:39 -0700203 java_lang_Class->SetDescriptor(intern_table_->InternStrong("Ljava/lang/Class;"));
204 java_lang_Object->SetDescriptor(intern_table_->InternStrong("Ljava/lang/Object;"));
Elliott Hughes418d20f2011-09-22 14:00:39 -0700205 class_array_class->SetDescriptor(intern_table_->InternStrong("[Ljava/lang/Class;"));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700206 object_array_class->SetDescriptor(intern_table_->InternStrong("[Ljava/lang/Object;"));
207 java_lang_String->SetDescriptor(intern_table_->InternStrong("Ljava/lang/String;"));
208 char_array_class->SetDescriptor(intern_table_->InternStrong("[C"));
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700209
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700210 // Create storage for root classes, save away our work so far (requires
211 // descriptors)
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700212 class_roots_ = ObjectArray<Class>::Alloc(object_array_class, kClassRootsMax);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700213 SetClassRoot(kJavaLangClass, java_lang_Class);
214 SetClassRoot(kJavaLangObject, java_lang_Object);
Elliott Hughes418d20f2011-09-22 14:00:39 -0700215 SetClassRoot(kClassArrayClass, class_array_class);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700216 SetClassRoot(kObjectArrayClass, object_array_class);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700217 SetClassRoot(kCharArrayClass, char_array_class);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700218 SetClassRoot(kJavaLangString, java_lang_String);
219
220 // Setup the primitive type classes.
221 SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass("Z", Class::kPrimBoolean));
222 SetClassRoot(kPrimitiveByte, CreatePrimitiveClass("B", Class::kPrimByte));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700223 SetClassRoot(kPrimitiveShort, CreatePrimitiveClass("S", Class::kPrimShort));
224 SetClassRoot(kPrimitiveInt, CreatePrimitiveClass("I", Class::kPrimInt));
225 SetClassRoot(kPrimitiveLong, CreatePrimitiveClass("J", Class::kPrimLong));
226 SetClassRoot(kPrimitiveFloat, CreatePrimitiveClass("F", Class::kPrimFloat));
227 SetClassRoot(kPrimitiveDouble, CreatePrimitiveClass("D", Class::kPrimDouble));
228 SetClassRoot(kPrimitiveVoid, CreatePrimitiveClass("V", Class::kPrimVoid));
229
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700230 // Create array interface entries to populate once we can load system classes
Elliott Hughes418d20f2011-09-22 14:00:39 -0700231 array_interfaces_ = AllocClassArray(2);
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700232 array_iftable_ = AllocObjectArray<InterfaceEntry>(2);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700233
234 // Create int array type for AllocDexCache (done in AppendToBootClassPath)
235 Class* int_array_class = AllocClass(java_lang_Class, sizeof(Class));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700236 int_array_class->SetDescriptor(intern_table_->InternStrong("[I"));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700237 int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
238 IntArray::SetArrayClass(int_array_class);
Elliott Hughesc1674ed2011-08-25 18:09:09 -0700239 SetClassRoot(kIntArrayClass, int_array_class);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700240
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700241 // now that these are registered, we can use AllocClass() and AllocObjectArray
Brian Carlstroma0808032011-07-18 00:39:23 -0700242
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700243 // setup boot_class_path_ and register class_path now that we can
244 // use AllocObjectArray to create DexCache instances
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700245 for (size_t i = 0; i != boot_class_path.size(); ++i) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700246 const DexFile* dex_file = boot_class_path[i];
247 CHECK(dex_file != NULL);
248 AppendToBootClassPath(*dex_file);
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700249 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700250 for (size_t i = 0; i != class_path.size(); ++i) {
251 const DexFile* dex_file = class_path[i];
252 CHECK(dex_file != NULL);
253 RegisterDexFile(*dex_file);
254 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700255
Elliott Hughes80609252011-09-23 17:24:51 -0700256 // Constructor, Field, and Method are necessary so that FindClass can link members
257 Class* java_lang_reflect_Constructor = AllocClass(java_lang_Class, sizeof(MethodClass));
258 java_lang_reflect_Constructor->SetDescriptor(intern_table_->InternStrong("Ljava/lang/reflect/Constructor;"));
259 CHECK(java_lang_reflect_Constructor != NULL);
260 java_lang_reflect_Constructor->SetObjectSize(sizeof(Method));
261 SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor);
262 java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved);
263
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700264 Class* java_lang_reflect_Field = AllocClass(java_lang_Class, sizeof(FieldClass));
265 CHECK(java_lang_reflect_Field != NULL);
Brian Carlstromc74255f2011-09-11 22:47:39 -0700266 java_lang_reflect_Field->SetDescriptor(intern_table_->InternStrong("Ljava/lang/reflect/Field;"));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700267 java_lang_reflect_Field->SetObjectSize(sizeof(Field));
268 SetClassRoot(kJavaLangReflectField, java_lang_reflect_Field);
269 java_lang_reflect_Field->SetStatus(Class::kStatusResolved);
270 Field::SetClass(java_lang_reflect_Field);
271
272 Class* java_lang_reflect_Method = AllocClass(java_lang_Class, sizeof(MethodClass));
Elliott Hughes80609252011-09-23 17:24:51 -0700273 java_lang_reflect_Method->SetDescriptor(intern_table_->InternStrong("Ljava/lang/reflect/Method;"));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700274 CHECK(java_lang_reflect_Method != NULL);
275 java_lang_reflect_Method->SetObjectSize(sizeof(Method));
276 SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method);
277 java_lang_reflect_Method->SetStatus(Class::kStatusResolved);
Elliott Hughes80609252011-09-23 17:24:51 -0700278 Method::SetClasses(java_lang_reflect_Constructor, java_lang_reflect_Method);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700279
280 // now we can use FindSystemClass
281
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700282 // run char class through InitializePrimitiveClass to finish init
283 InitializePrimitiveClass(char_class, "C", Class::kPrimChar);
284 SetClassRoot(kPrimitiveChar, char_class); // needs descriptor
285
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700286 // Object and String need to be rerun through FindSystemClass to finish init
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700287 java_lang_Object->SetStatus(Class::kStatusNotReady);
288 Class* Object_class = FindSystemClass("Ljava/lang/Object;");
289 CHECK_EQ(java_lang_Object, Object_class);
290 CHECK_EQ(java_lang_Object->GetObjectSize(), sizeof(Object));
291 java_lang_String->SetStatus(Class::kStatusNotReady);
292 Class* String_class = FindSystemClass("Ljava/lang/String;");
293 CHECK_EQ(java_lang_String, String_class);
294 CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(String));
295
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700296 // Setup the primitive array type classes - can't be done until Object has a vtable
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700297 SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
298 BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
299
300 SetClassRoot(kByteArrayClass, FindSystemClass("[B"));
301 ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
302
303 Class* found_char_array_class = FindSystemClass("[C");
304 CHECK_EQ(char_array_class, found_char_array_class);
305
306 SetClassRoot(kShortArrayClass, FindSystemClass("[S"));
307 ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
308
309 Class* found_int_array_class = FindSystemClass("[I");
310 CHECK_EQ(int_array_class, found_int_array_class);
311
312 SetClassRoot(kLongArrayClass, FindSystemClass("[J"));
313 LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
314
315 SetClassRoot(kFloatArrayClass, FindSystemClass("[F"));
316 FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
317
318 SetClassRoot(kDoubleArrayClass, FindSystemClass("[D"));
319 DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
320
Elliott Hughes418d20f2011-09-22 14:00:39 -0700321 Class* found_class_array_class = FindSystemClass("[Ljava/lang/Class;");
322 CHECK_EQ(class_array_class, found_class_array_class);
323
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700324 Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
325 CHECK_EQ(object_array_class, found_object_array_class);
326
327 // Setup the single, global copies of "interfaces" and "iftable"
328 Class* java_lang_Cloneable = FindSystemClass("Ljava/lang/Cloneable;");
329 CHECK(java_lang_Cloneable != NULL);
330 Class* java_io_Serializable = FindSystemClass("Ljava/io/Serializable;");
331 CHECK(java_io_Serializable != NULL);
332 CHECK(array_interfaces_ != NULL);
333 array_interfaces_->Set(0, java_lang_Cloneable);
334 array_interfaces_->Set(1, java_io_Serializable);
335 // We assume that Cloneable/Serializable don't have superinterfaces --
336 // normally we'd have to crawl up and explicitly list all of the
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700337 // supers as well.
338 array_iftable_->Set(0, AllocInterfaceEntry(array_interfaces_->Get(0)));
339 array_iftable_->Set(1, AllocInterfaceEntry(array_interfaces_->Get(1)));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700340
Elliott Hughes418d20f2011-09-22 14:00:39 -0700341 // Sanity check Class[] and Object[]'s interfaces
342 CHECK_EQ(java_lang_Cloneable, class_array_class->GetInterface(0));
343 CHECK_EQ(java_io_Serializable, class_array_class->GetInterface(1));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700344 CHECK_EQ(java_lang_Cloneable, object_array_class->GetInterface(0));
345 CHECK_EQ(java_io_Serializable, object_array_class->GetInterface(1));
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700346
Elliott Hughes80609252011-09-23 17:24:51 -0700347 // run Class, Constructor, Field, and Method through FindSystemClass.
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700348 // this initializes their dex_cache_ fields and register them in classes_.
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700349 Class* Class_class = FindSystemClass("Ljava/lang/Class;");
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700350 CHECK_EQ(java_lang_Class, Class_class);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700351
Elliott Hughes80609252011-09-23 17:24:51 -0700352 java_lang_reflect_Constructor->SetStatus(Class::kStatusNotReady);
353 Class* Constructor_class = FindSystemClass("Ljava/lang/reflect/Constructor;");
354 CHECK_EQ(java_lang_reflect_Constructor, Constructor_class);
355
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700356 java_lang_reflect_Field->SetStatus(Class::kStatusNotReady);
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700357 Class* Field_class = FindSystemClass("Ljava/lang/reflect/Field;");
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700358 CHECK_EQ(java_lang_reflect_Field, Field_class);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700359
360 java_lang_reflect_Method->SetStatus(Class::kStatusNotReady);
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700361 Class* Method_class = FindSystemClass("Ljava/lang/reflect/Method;");
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700362 CHECK_EQ(java_lang_reflect_Method, Method_class);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700363
364 // java.lang.ref classes need to be specially flagged, but otherwise are normal classes
365 Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700366 java_lang_ref_FinalizerReference->SetAccessFlags(
367 java_lang_ref_FinalizerReference->GetAccessFlags() |
368 kAccClassIsReference | kAccClassIsFinalizerReference);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700369 Class* java_lang_ref_PhantomReference = FindSystemClass("Ljava/lang/ref/PhantomReference;");
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700370 java_lang_ref_PhantomReference->SetAccessFlags(
371 java_lang_ref_PhantomReference->GetAccessFlags() |
372 kAccClassIsReference | kAccClassIsPhantomReference);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700373 Class* java_lang_ref_SoftReference = FindSystemClass("Ljava/lang/ref/SoftReference;");
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700374 java_lang_ref_SoftReference->SetAccessFlags(
375 java_lang_ref_SoftReference->GetAccessFlags() | kAccClassIsReference);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700376 Class* java_lang_ref_WeakReference = FindSystemClass("Ljava/lang/ref/WeakReference;");
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700377 java_lang_ref_WeakReference->SetAccessFlags(
378 java_lang_ref_WeakReference->GetAccessFlags() |
379 kAccClassIsReference | kAccClassIsWeakReference);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700380
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700381 // Setup the ClassLoaders, adjusting the object_size_ as necessary
382 Class* java_lang_ClassLoader = FindSystemClass("Ljava/lang/ClassLoader;");
383 CHECK_LT(java_lang_ClassLoader->GetObjectSize(), sizeof(ClassLoader));
384 java_lang_ClassLoader->SetObjectSize(sizeof(ClassLoader));
385 SetClassRoot(kJavaLangClassLoader, java_lang_ClassLoader);
386
387 Class* dalvik_system_BaseDexClassLoader = FindSystemClass("Ldalvik/system/BaseDexClassLoader;");
388 CHECK_EQ(dalvik_system_BaseDexClassLoader->GetObjectSize(), sizeof(BaseDexClassLoader));
389 SetClassRoot(kDalvikSystemBaseDexClassLoader, dalvik_system_BaseDexClassLoader);
390
391 Class* dalvik_system_PathClassLoader = FindSystemClass("Ldalvik/system/PathClassLoader;");
392 CHECK_EQ(dalvik_system_PathClassLoader->GetObjectSize(), sizeof(PathClassLoader));
393 SetClassRoot(kDalvikSystemPathClassLoader, dalvik_system_PathClassLoader);
394 PathClassLoader::SetClass(dalvik_system_PathClassLoader);
395
396 // Set up java.lang.StackTraceElement as a convenience
Brian Carlstrom1f870082011-08-23 16:02:11 -0700397 SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;"));
398 SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;"));
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700399 StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700400
Brian Carlstroma663ea52011-08-19 23:33:41 -0700401 FinishInit();
402}
403
404void ClassLinker::FinishInit() {
Brian Carlstrom16192862011-09-12 17:50:06 -0700405
406 // Let the heap know some key offsets into java.lang.ref instances
407 // NB we hard code the field indexes here rather than using FindInstanceField
408 // as the types of the field can't be resolved prior to the runtime being
409 // fully initialized
410 Class* java_lang_ref_Reference = FindSystemClass("Ljava/lang/ref/Reference;");
411 Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
412
413 Field* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
414 CHECK(pendingNext->GetName()->Equals("pendingNext"));
415 CHECK_EQ(ResolveType(pendingNext->GetTypeIdx(), pendingNext), java_lang_ref_Reference);
416
417 Field* queue = java_lang_ref_Reference->GetInstanceField(1);
418 CHECK(queue->GetName()->Equals("queue"));
419 CHECK_EQ(ResolveType(queue->GetTypeIdx(), queue),
420 FindSystemClass("Ljava/lang/ref/ReferenceQueue;"));
421
422 Field* queueNext = java_lang_ref_Reference->GetInstanceField(2);
423 CHECK(queueNext->GetName()->Equals("queueNext"));
424 CHECK_EQ(ResolveType(queueNext->GetTypeIdx(), queueNext), java_lang_ref_Reference);
425
426 Field* referent = java_lang_ref_Reference->GetInstanceField(3);
427 CHECK(referent->GetName()->Equals("referent"));
428 CHECK_EQ(ResolveType(referent->GetTypeIdx(), referent), GetClassRoot(kJavaLangObject));
429
430 Field* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
431 CHECK(zombie->GetName()->Equals("zombie"));
432 CHECK_EQ(ResolveType(zombie->GetTypeIdx(), zombie), GetClassRoot(kJavaLangObject));
433
434 Heap::SetReferenceOffsets(referent->GetOffset(),
435 queue->GetOffset(),
436 queueNext->GetOffset(),
437 pendingNext->GetOffset(),
438 zombie->GetOffset());
439
Brian Carlstroma663ea52011-08-19 23:33:41 -0700440 // ensure all class_roots_ are initialized
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700441 for (size_t i = 0; i < kClassRootsMax; i++) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700442 ClassRoot class_root = static_cast<ClassRoot>(i);
443 Class* klass = GetClassRoot(class_root);
444 CHECK(klass != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700445 DCHECK(klass->IsArrayClass() || klass->IsPrimitive() || klass->GetDexCache() != NULL);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700446 // note SetClassRoot does additional validation.
447 // if possible add new checks there to catch errors early
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700448 }
449
450 // disable the slow paths in FindClass and CreatePrimitiveClass now
451 // that Object, Class, and Object[] are setup
452 init_done_ = true;
453}
454
Elliott Hughes2a20cfd2011-09-23 19:30:41 -0700455void ClassLinker::RunRootClinits() {
456 Thread* self = Thread::Current();
457 for (size_t i = 0; i < ClassLinker::kClassRootsMax; ++i) {
458 Class* c = GetClassRoot(ClassRoot(i));
459 if (!c->IsArrayClass() && !c->IsPrimitive()) {
460 EnsureInitialized(GetClassRoot(ClassRoot(i)), true);
461 CHECK(!self->IsExceptionPending());
462 }
463 }
464}
465
Brian Carlstromc74255f2011-09-11 22:47:39 -0700466struct ClassLinker::InitFromImageCallbackState {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700467 ClassLinker* class_linker;
468
469 Class* class_roots[kClassRootsMax];
470
471 typedef std::tr1::unordered_map<std::string, ClassRoot> Table;
472 Table descriptor_to_class_root;
473
Brian Carlstroma663ea52011-08-19 23:33:41 -0700474 typedef std::tr1::unordered_set<DexCache*, DexCacheHash> Set;
475 Set dex_caches;
476};
477
Brian Carlstromc74255f2011-09-11 22:47:39 -0700478void ClassLinker::InitFromImage(const std::vector<const DexFile*>& boot_class_path,
479 const std::vector<const DexFile*>& class_path) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700480 CHECK(!init_done_);
481
482 HeapBitmap* heap_bitmap = Heap::GetLiveBits();
483 DCHECK(heap_bitmap != NULL);
484
Brian Carlstromc74255f2011-09-11 22:47:39 -0700485 InitFromImageCallbackState state;
Brian Carlstroma663ea52011-08-19 23:33:41 -0700486 state.class_linker = this;
487 for (size_t i = 0; i < kClassRootsMax; i++) {
488 ClassRoot class_root = static_cast<ClassRoot>(i);
489 state.descriptor_to_class_root[GetClassRootDescriptor(class_root)] = class_root;
490 }
491
492 // reinit clases_ table
Brian Carlstromc74255f2011-09-11 22:47:39 -0700493 heap_bitmap->Walk(InitFromImageCallback, &state);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700494
495 // reinit class_roots_
496 Class* object_array_class = state.class_roots[kObjectArrayClass];
497 class_roots_ = ObjectArray<Class>::Alloc(object_array_class, kClassRootsMax);
498 for (size_t i = 0; i < kClassRootsMax; i++) {
499 ClassRoot class_root = static_cast<ClassRoot>(i);
500 SetClassRoot(class_root, state.class_roots[class_root]);
501 }
502
Brian Carlstroma663ea52011-08-19 23:33:41 -0700503 // reinit array_interfaces_ from any array class instance, they should all be ==
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700504 array_interfaces_ = GetClassRoot(kObjectArrayClass)->GetInterfaces();
505 DCHECK(array_interfaces_ == GetClassRoot(kBooleanArrayClass)->GetInterfaces());
Brian Carlstroma663ea52011-08-19 23:33:41 -0700506
507 // build a map from location to DexCache to match up with DexFile::GetLocation
508 std::tr1::unordered_map<std::string, DexCache*> location_to_dex_cache;
Brian Carlstromc74255f2011-09-11 22:47:39 -0700509 typedef InitFromImageCallbackState::Set::const_iterator It; // TODO: C++0x auto
Brian Carlstroma663ea52011-08-19 23:33:41 -0700510 for (It it = state.dex_caches.begin(), end = state.dex_caches.end(); it != end; ++it) {
511 DexCache* dex_cache = *it;
512 std::string location = dex_cache->GetLocation()->ToModifiedUtf8();
513 location_to_dex_cache[location] = dex_cache;
514 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700515 CHECK_EQ(boot_class_path.size() + class_path.size(),
516 location_to_dex_cache.size());
Brian Carlstroma663ea52011-08-19 23:33:41 -0700517
518 // reinit boot_class_path with DexFile arguments and found DexCaches
519 for (size_t i = 0; i != boot_class_path.size(); ++i) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700520 const DexFile* dex_file = boot_class_path[i];
521 CHECK(dex_file != NULL);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700522 DexCache* dex_cache = location_to_dex_cache[dex_file->GetLocation()];
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700523 CHECK(dex_cache != NULL) << dex_file->GetLocation();
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700524 AppendToBootClassPath(*dex_file, dex_cache);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700525 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700526
527 // register class_path with DexFile arguments and found DexCaches
528 for (size_t i = 0; i != class_path.size(); ++i) {
529 const DexFile* dex_file = class_path[i];
530 CHECK(dex_file != NULL);
531 DexCache* dex_cache = location_to_dex_cache[dex_file->GetLocation()];
532 CHECK(dex_cache != NULL) << dex_file->GetLocation();
533 RegisterDexFile(*dex_file, dex_cache);
534 }
535
Brian Carlstroma663ea52011-08-19 23:33:41 -0700536 String::SetClass(GetClassRoot(kJavaLangString));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700537 Field::SetClass(GetClassRoot(kJavaLangReflectField));
Elliott Hughes80609252011-09-23 17:24:51 -0700538 Method::SetClasses(GetClassRoot(kJavaLangReflectConstructor), GetClassRoot(kJavaLangReflectMethod));
Brian Carlstroma663ea52011-08-19 23:33:41 -0700539 BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
540 ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
541 CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
542 DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
543 FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
544 IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
545 LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
546 ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700547 PathClassLoader::SetClass(GetClassRoot(kDalvikSystemPathClassLoader));
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700548 StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
Brian Carlstroma663ea52011-08-19 23:33:41 -0700549
550 FinishInit();
551}
552
Brian Carlstrom78128a62011-09-15 17:21:19 -0700553void ClassLinker::InitFromImageCallback(Object* obj, void* arg) {
Brian Carlstroma663ea52011-08-19 23:33:41 -0700554 DCHECK(obj != NULL);
555 DCHECK(arg != NULL);
Brian Carlstromc74255f2011-09-11 22:47:39 -0700556 InitFromImageCallbackState* state = reinterpret_cast<InitFromImageCallbackState*>(arg);
Brian Carlstroma663ea52011-08-19 23:33:41 -0700557
Brian Carlstromc74255f2011-09-11 22:47:39 -0700558 if (obj->IsString()) {
559 state->class_linker->intern_table_->RegisterStrong(obj->AsString());
560 return;
561 }
Brian Carlstroma663ea52011-08-19 23:33:41 -0700562 if (!obj->IsClass()) {
563 return;
564 }
565 Class* klass = obj->AsClass();
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700566 // TODO: restore ClassLoader's list of DexFiles after image load
567 // CHECK(klass->GetClassLoader() == NULL);
568 const ClassLoader* class_loader = klass->GetClassLoader();
569 if (class_loader != NULL) {
570 // TODO: replace this hack with something based on command line arguments
571 Thread::Current()->SetClassLoaderOverride(class_loader);
572 }
Brian Carlstroma663ea52011-08-19 23:33:41 -0700573
574 std::string descriptor = klass->GetDescriptor()->ToModifiedUtf8();
Brian Carlstroma663ea52011-08-19 23:33:41 -0700575 // restore class to ClassLinker::classes_ table
576 state->class_linker->InsertClass(descriptor, klass);
577
578 // note DexCache to match with DexFile later
579 DexCache* dex_cache = klass->GetDexCache();
580 if (dex_cache != NULL) {
581 state->dex_caches.insert(dex_cache);
582 } else {
Brian Carlstromb63ec392011-08-27 17:38:27 -0700583 DCHECK(klass->IsArrayClass() || klass->IsPrimitive());
Brian Carlstroma663ea52011-08-19 23:33:41 -0700584 }
585
586 // check if this is a root, if so, register it
Brian Carlstromc74255f2011-09-11 22:47:39 -0700587 typedef InitFromImageCallbackState::Table::const_iterator It; // TODO: C++0x auto
Brian Carlstroma663ea52011-08-19 23:33:41 -0700588 It it = state->descriptor_to_class_root.find(descriptor);
589 if (it != state->descriptor_to_class_root.end()) {
590 ClassRoot class_root = it->second;
591 state->class_roots[class_root] = klass;
592 }
593}
594
595// Keep in sync with InitCallback. Anything we visit, we need to
596// reinit references to when reinitializing a ClassLinker from a
597// mapped image.
Elliott Hughes410c0c82011-09-01 17:58:25 -0700598void ClassLinker::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
599 visitor(class_roots_, arg);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700600
601 for (size_t i = 0; i < dex_caches_.size(); i++) {
Elliott Hughes410c0c82011-09-01 17:58:25 -0700602 visitor(dex_caches_[i], arg);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700603 }
604
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700605 {
Brian Carlstrom16192862011-09-12 17:50:06 -0700606 MutexLock mu(lock_);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700607 typedef Table::const_iterator It; // TODO: C++0x auto
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700608 for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
Elliott Hughes410c0c82011-09-01 17:58:25 -0700609 visitor(it->second, arg);
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700610 }
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700611 }
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700612
Elliott Hughes410c0c82011-09-01 17:58:25 -0700613 visitor(array_interfaces_, arg);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700614}
615
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700616ClassLinker::~ClassLinker() {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700617 String::ResetClass();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700618 Field::ResetClass();
Elliott Hughes80609252011-09-23 17:24:51 -0700619 Method::ResetClasses();
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700620 BooleanArray::ResetArrayClass();
621 ByteArray::ResetArrayClass();
622 CharArray::ResetArrayClass();
623 DoubleArray::ResetArrayClass();
624 FloatArray::ResetArrayClass();
625 IntArray::ResetArrayClass();
626 LongArray::ResetArrayClass();
627 ShortArray::ResetArrayClass();
628 PathClassLoader::ResetClass();
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700629 StackTraceElement::ResetClass();
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700630}
631
632DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700633 DexCache* dex_cache = down_cast<DexCache*>(AllocObjectArray<Object>(DexCache::LengthAsArray()));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700634 dex_cache->Init(intern_table_->InternStrong(dex_file.GetLocation().c_str()),
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700635 AllocObjectArray<String>(dex_file.NumStringIds()),
Elliott Hughes418d20f2011-09-22 14:00:39 -0700636 AllocClassArray(dex_file.NumTypeIds()),
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700637 AllocObjectArray<Method>(dex_file.NumMethodIds()),
Brian Carlstrom83db7722011-08-26 17:32:56 -0700638 AllocObjectArray<Field>(dex_file.NumFieldIds()),
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700639 AllocCodeAndDirectMethods(dex_file.NumMethodIds()),
640 AllocObjectArray<StaticStorageBase>(dex_file.NumTypeIds()));
Brian Carlstroma663ea52011-08-19 23:33:41 -0700641 return dex_cache;
Brian Carlstroma0808032011-07-18 00:39:23 -0700642}
643
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700644CodeAndDirectMethods* ClassLinker::AllocCodeAndDirectMethods(size_t length) {
645 return down_cast<CodeAndDirectMethods*>(IntArray::Alloc(CodeAndDirectMethods::LengthAsArray(length)));
Brian Carlstrom83db7722011-08-26 17:32:56 -0700646}
647
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700648InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) {
649 DCHECK(interface->IsInterface());
650 ObjectArray<Object>* array = AllocObjectArray<Object>(InterfaceEntry::LengthAsArray());
651 InterfaceEntry* interface_entry = down_cast<InterfaceEntry*>(array);
652 interface_entry->SetInterface(interface);
653 return interface_entry;
654}
655
Brian Carlstrom4873d462011-08-21 15:23:39 -0700656Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
657 DCHECK_GE(class_size, sizeof(Class));
658 Class* klass = Heap::AllocObject(java_lang_Class, class_size)->AsClass();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700659 klass->SetPrimitiveType(Class::kPrimNot); // default to not being primitive
660 klass->SetClassSize(class_size);
Brian Carlstrom4873d462011-08-21 15:23:39 -0700661 return klass;
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700662}
663
Brian Carlstrom4873d462011-08-21 15:23:39 -0700664Class* ClassLinker::AllocClass(size_t class_size) {
665 return AllocClass(GetClassRoot(kJavaLangClass), class_size);
Brian Carlstroma0808032011-07-18 00:39:23 -0700666}
667
Jesse Wilson35baaab2011-08-10 16:18:03 -0400668Field* ClassLinker::AllocField() {
Brian Carlstrom1f870082011-08-23 16:02:11 -0700669 return down_cast<Field*>(GetClassRoot(kJavaLangReflectField)->AllocObject());
Brian Carlstroma0808032011-07-18 00:39:23 -0700670}
671
672Method* ClassLinker::AllocMethod() {
Brian Carlstrom1f870082011-08-23 16:02:11 -0700673 return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject());
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700674}
675
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700676ObjectArray<StackTraceElement>* ClassLinker::AllocStackTraceElementArray(size_t length) {
677 return ObjectArray<StackTraceElement>::Alloc(
678 GetClassRoot(kJavaLangStackTraceElementArrayClass),
679 length);
680}
681
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700682Class* ClassLinker::FindClass(const StringPiece& descriptor,
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700683 const ClassLoader* class_loader) {
Brian Carlstrom4a289ed2011-08-16 17:17:49 -0700684 // TODO: remove this contrived parent class loader check when we have a real ClassLoader.
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700685 if (class_loader != NULL) {
686 Class* klass = FindClass(descriptor, NULL);
687 if (klass != NULL) {
688 return klass;
689 }
Elliott Hughesbd935992011-08-22 11:59:34 -0700690 Thread::Current()->ClearException();
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700691 }
692
Carl Shapirob5573532011-07-12 18:22:59 -0700693 Thread* self = Thread::Current();
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700694 DCHECK(self != NULL);
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700695 CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700696 // Find the class in the loaded classes table.
697 Class* klass = LookupClass(descriptor, class_loader);
698 if (klass == NULL) {
699 // Class is not yet loaded.
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700700 if (descriptor[0] == '[' && descriptor[1] != '\0') {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700701 return CreateArrayClass(descriptor, class_loader);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700702 }
Brian Carlstrom8a487412011-08-29 20:08:52 -0700703 const DexFile::ClassPath& class_path = ((class_loader != NULL)
704 ? ClassLoader::GetClassPath(class_loader)
705 : boot_class_path_);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700706 DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, class_path);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700707 if (pair.second == NULL) {
Elliott Hughesbd935992011-08-22 11:59:34 -0700708 std::string name(PrintableString(descriptor));
Elliott Hughes4a2b4172011-09-20 17:08:25 -0700709 ThrowNoClassDefFoundError("Class %s not found in class loader %p", name.c_str(), class_loader);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700710 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700711 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700712 const DexFile& dex_file = *pair.first;
713 const DexFile::ClassDef& dex_class_def = *pair.second;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700714 DexCache* dex_cache = FindDexCache(dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700715 // Load the class from the dex file.
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700716 if (!init_done_) {
717 // finish up init of hand crafted class_roots_
718 if (descriptor == "Ljava/lang/Object;") {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700719 klass = GetClassRoot(kJavaLangObject);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700720 } else if (descriptor == "Ljava/lang/Class;") {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700721 klass = GetClassRoot(kJavaLangClass);
Jesse Wilson14150742011-07-29 19:04:44 -0400722 } else if (descriptor == "Ljava/lang/String;") {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700723 klass = GetClassRoot(kJavaLangString);
Elliott Hughes80609252011-09-23 17:24:51 -0700724 } else if (descriptor == "Ljava/lang/reflect/Constructor;") {
725 klass = GetClassRoot(kJavaLangReflectConstructor);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700726 } else if (descriptor == "Ljava/lang/reflect/Field;") {
727 klass = GetClassRoot(kJavaLangReflectField);
728 } else if (descriptor == "Ljava/lang/reflect/Method;") {
729 klass = GetClassRoot(kJavaLangReflectMethod);
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700730 } else {
Brian Carlstrom4873d462011-08-21 15:23:39 -0700731 klass = AllocClass(SizeOfClass(dex_file, dex_class_def));
Brian Carlstrom75cb3b42011-07-28 02:13:36 -0700732 }
Carl Shapiro565f5072011-07-10 13:39:43 -0700733 } else {
Brian Carlstrom4873d462011-08-21 15:23:39 -0700734 klass = AllocClass(SizeOfClass(dex_file, dex_class_def));
Carl Shapiro565f5072011-07-10 13:39:43 -0700735 }
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700736 if (!klass->IsResolved()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700737 klass->SetDexCache(dex_cache);
738 LoadClass(dex_file, dex_class_def, klass, class_loader);
739 // Check for a pending exception during load
740 if (self->IsExceptionPending()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700741 return NULL;
742 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700743 ObjectLock lock(klass);
Elliott Hughesdcc24742011-09-07 14:02:44 -0700744 klass->SetClinitThreadId(self->GetTid());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700745 // Add the newly loaded class to the loaded classes table.
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700746 bool success = InsertClass(descriptor, klass); // TODO: just return collision
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700747 if (!success) {
748 // We may fail to insert if we raced with another thread.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700749 klass->SetClinitThreadId(0);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700750 klass = LookupClass(descriptor, class_loader);
751 CHECK(klass != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700752 return klass;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700753 } else {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700754 // Finish loading (if necessary) by finding parents
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700755 CHECK(!klass->IsLoaded());
756 if (!LoadSuperAndInterfaces(klass, dex_file)) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700757 // Loading failed.
Elliott Hughes4a2b4172011-09-20 17:08:25 -0700758 CHECK(self->IsExceptionPending());
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700759 lock.NotifyAll();
760 return NULL;
761 }
762 CHECK(klass->IsLoaded());
763 // Link the class (if necessary)
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700764 CHECK(!klass->IsResolved());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700765 if (!LinkClass(klass)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700766 // Linking failed.
Elliott Hughes4a2b4172011-09-20 17:08:25 -0700767 CHECK(self->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700768 lock.NotifyAll();
769 return NULL;
770 }
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700771 CHECK(klass->IsResolved());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700772 }
773 }
774 }
775 // Link the class if it has not already been linked.
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700776 if (!klass->IsResolved() && !klass->IsErroneous()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700777 ObjectLock lock(klass);
778 // Check for circular dependencies between classes.
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700779 if (!klass->IsResolved() && klass->GetClinitThreadId() == self->GetTid()) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -0700780 self->ThrowNewException("Ljava/lang/ClassCircularityError;", "%s",
781 PrettyDescriptor(klass->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700782 return NULL;
783 }
784 // Wait for the pending initialization to complete.
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700785 while (!klass->IsResolved() && !klass->IsErroneous()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700786 lock.Wait();
787 }
788 }
789 if (klass->IsErroneous()) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -0700790 ThrowEarlierClassFailure(klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700791 return NULL;
792 }
793 // Return the loaded class. No exceptions should be pending.
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700794 CHECK(klass->IsResolved());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700795 CHECK(!self->IsExceptionPending());
796 return klass;
797}
798
Brian Carlstrom4873d462011-08-21 15:23:39 -0700799// Precomputes size that will be needed for Class, matching LinkStaticFields
800size_t ClassLinker::SizeOfClass(const DexFile& dex_file,
801 const DexFile::ClassDef& dex_class_def) {
802 const byte* class_data = dex_file.GetClassData(dex_class_def);
803 DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data);
804 size_t num_static_fields = header.static_fields_size_;
805 size_t num_ref = 0;
806 size_t num_32 = 0;
807 size_t num_64 = 0;
808 if (num_static_fields != 0) {
809 uint32_t last_idx = 0;
810 for (size_t i = 0; i < num_static_fields; ++i) {
811 DexFile::Field dex_field;
812 dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx);
813 const DexFile::FieldId& field_id = dex_file.GetFieldId(dex_field.field_idx_);
814 const char* descriptor = dex_file.dexStringByTypeIdx(field_id.type_idx_);
815 char c = descriptor[0];
816 if (c == 'L' || c == '[') {
817 num_ref++;
818 } else if (c == 'J' || c == 'D') {
819 num_64++;
820 } else {
821 num_32++;
822 }
823 }
824 }
825
826 // start with generic class data
827 size_t size = sizeof(Class);
828 // follow with reference fields which must be contiguous at start
829 size += (num_ref * sizeof(uint32_t));
830 // if there are 64-bit fields to add, make sure they are aligned
831 if (num_64 != 0 && size != RoundUp(size, 8)) { // for 64-bit alignment
832 if (num_32 != 0) {
833 // use an available 32-bit field for padding
834 num_32--;
835 }
836 size += sizeof(uint32_t); // either way, we are adding a word
837 DCHECK_EQ(size, RoundUp(size, 8));
838 }
839 // tack on any 64-bit fields now that alignment is assured
840 size += (num_64 * sizeof(uint64_t));
841 // tack on any remaining 32-bit fields
842 size += (num_32 * sizeof(uint32_t));
843 return size;
844}
845
Brian Carlstromf615a612011-07-23 12:50:34 -0700846void ClassLinker::LoadClass(const DexFile& dex_file,
847 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700848 Class* klass,
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700849 const ClassLoader* class_loader) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700850 CHECK(klass != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700851 CHECK(klass->GetDexCache() != NULL);
852 CHECK_EQ(Class::kStatusNotReady, klass->GetStatus());
Brian Carlstromf615a612011-07-23 12:50:34 -0700853 const byte* class_data = dex_file.GetClassData(dex_class_def);
854 DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700855
Brian Carlstromf615a612011-07-23 12:50:34 -0700856 const char* descriptor = dex_file.GetClassDescriptor(dex_class_def);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700857 CHECK(descriptor != NULL);
858
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700859 klass->SetClass(GetClassRoot(kJavaLangClass));
860 if (klass->GetDescriptor() != NULL) {
861 DCHECK(klass->GetDescriptor()->Equals(descriptor));
862 } else {
Brian Carlstromc74255f2011-09-11 22:47:39 -0700863 klass->SetDescriptor(intern_table_->InternStrong(descriptor));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700864 }
865 uint32_t access_flags = dex_class_def.access_flags_;
866 // Make sure there aren't any "bonus" flags set, since we use them for runtime
867 // state.
868 CHECK_EQ(access_flags & ~kAccClassFlagsMask, 0U);
869 klass->SetAccessFlags(access_flags);
870 klass->SetClassLoader(class_loader);
871 DCHECK(klass->GetPrimitiveType() == Class::kPrimNot);
872 klass->SetStatus(Class::kStatusIdx);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700873
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700874 klass->SetSuperClassTypeIdx(dex_class_def.superclass_idx_);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700875
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700876 size_t num_static_fields = header.static_fields_size_;
877 size_t num_instance_fields = header.instance_fields_size_;
878 size_t num_direct_methods = header.direct_methods_size_;
879 size_t num_virtual_methods = header.virtual_methods_size_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700880
Brian Carlstromc74255f2011-09-11 22:47:39 -0700881 klass->SetSourceFile(intern_table_->InternStrong(dex_file.dexGetSourceFile(dex_class_def)));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700882
883 // Load class interfaces.
Brian Carlstromf615a612011-07-23 12:50:34 -0700884 LoadInterfaces(dex_file, dex_class_def, klass);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700885
886 // Load static fields.
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700887 if (num_static_fields != 0) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700888 klass->SetSFields(AllocObjectArray<Field>(num_static_fields));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700889 uint32_t last_idx = 0;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700890 for (size_t i = 0; i < num_static_fields; ++i) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700891 DexFile::Field dex_field;
892 dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx);
Jesse Wilson35baaab2011-08-10 16:18:03 -0400893 Field* sfield = AllocField();
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700894 klass->SetStaticField(i, sfield);
Brian Carlstromf615a612011-07-23 12:50:34 -0700895 LoadField(dex_file, dex_field, klass, sfield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700896 }
897 }
898
899 // Load instance fields.
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700900 if (num_instance_fields != 0) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700901 klass->SetIFields(AllocObjectArray<Field>(num_instance_fields));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700902 uint32_t last_idx = 0;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700903 for (size_t i = 0; i < num_instance_fields; ++i) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700904 DexFile::Field dex_field;
905 dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx);
Jesse Wilson35baaab2011-08-10 16:18:03 -0400906 Field* ifield = AllocField();
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700907 klass->SetInstanceField(i, ifield);
Brian Carlstromf615a612011-07-23 12:50:34 -0700908 LoadField(dex_file, dex_field, klass, ifield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700909 }
910 }
911
912 // Load direct methods.
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700913 if (num_direct_methods != 0) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700914 // TODO: append direct methods to class object
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700915 klass->SetDirectMethods(AllocObjectArray<Method>(num_direct_methods));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700916 uint32_t last_idx = 0;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700917 for (size_t i = 0; i < num_direct_methods; ++i) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700918 DexFile::Method dex_method;
919 dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700920 Method* meth = AllocMethod();
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700921 klass->SetDirectMethod(i, meth);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700922 LoadMethod(dex_file, dex_method, klass, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700923 // TODO: register maps
924 }
925 }
926
927 // Load virtual methods.
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700928 if (num_virtual_methods != 0) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700929 // TODO: append virtual methods to class object
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700930 klass->SetVirtualMethods(AllocObjectArray<Method>(num_virtual_methods));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700931 uint32_t last_idx = 0;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700932 for (size_t i = 0; i < num_virtual_methods; ++i) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700933 DexFile::Method dex_method;
934 dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700935 Method* meth = AllocMethod();
Brian Carlstrom913af1b2011-07-23 21:41:13 -0700936 klass->SetVirtualMethod(i, meth);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700937 LoadMethod(dex_file, dex_method, klass, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700938 // TODO: register maps
939 }
940 }
Brian Carlstrom934486c2011-07-12 23:42:50 -0700941}
942
Brian Carlstromf615a612011-07-23 12:50:34 -0700943void ClassLinker::LoadInterfaces(const DexFile& dex_file,
944 const DexFile::ClassDef& dex_class_def,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700945 Class* klass) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700946 const DexFile::TypeList* list = dex_file.GetInterfacesList(dex_class_def);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700947 if (list != NULL) {
Elliott Hughes418d20f2011-09-22 14:00:39 -0700948 klass->SetInterfaces(AllocClassArray(list->Size()));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700949 IntArray* interfaces_idx = IntArray::Alloc(list->Size());
950 klass->SetInterfacesTypeIdx(interfaces_idx);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700951 for (size_t i = 0; i < list->Size(); ++i) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700952 const DexFile::TypeItem& type_item = list->GetTypeItem(i);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700953 interfaces_idx->Set(i, type_item.type_idx_);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700954 }
955 }
956}
957
Brian Carlstromf615a612011-07-23 12:50:34 -0700958void ClassLinker::LoadField(const DexFile& dex_file,
959 const DexFile::Field& src,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700960 Class* klass,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700961 Field* dst) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700962 const DexFile::FieldId& field_id = dex_file.GetFieldId(src.field_idx_);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700963 dst->SetDeclaringClass(klass);
964 dst->SetName(ResolveString(dex_file, field_id.name_idx_, klass->GetDexCache()));
965 dst->SetTypeIdx(field_id.type_idx_);
966 dst->SetAccessFlags(src.access_flags_);
967
968 // In order to access primitive types using GetTypeDuringLinking we need to
969 // ensure they are resolved into the dex cache
970 const char* descriptor = dex_file.dexStringByTypeIdx(field_id.type_idx_);
971 if (descriptor[1] == '\0') {
972 // only the descriptors of primitive types should be 1 character long
973 Class* resolved = ResolveType(dex_file, field_id.type_idx_, klass);
974 DCHECK(resolved->IsPrimitive());
975 }
Brian Carlstrom934486c2011-07-12 23:42:50 -0700976}
977
Brian Carlstromf615a612011-07-23 12:50:34 -0700978void ClassLinker::LoadMethod(const DexFile& dex_file,
979 const DexFile::Method& src,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700980 Class* klass,
Brian Carlstrom1f870082011-08-23 16:02:11 -0700981 Method* dst) {
Brian Carlstromf615a612011-07-23 12:50:34 -0700982 const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700983 dst->SetDeclaringClass(klass);
Elliott Hughes80609252011-09-23 17:24:51 -0700984 String* method_name = ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache());
985 dst->SetName(method_name);
986 if (method_name->Equals("<init>")) {
987 dst->SetClass(GetClassRoot(kJavaLangReflectConstructor));
988 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700989 {
990 int32_t utf16_length;
Elliott Hughes0c424cb2011-08-26 10:16:25 -0700991 std::string utf8(dex_file.CreateMethodDescriptor(method_id.proto_idx_, &utf16_length));
Brian Carlstromc74255f2011-09-11 22:47:39 -0700992 dst->SetSignature(intern_table_->InternStrong(utf16_length, utf8.c_str()));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700993 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700994 dst->SetProtoIdx(method_id.proto_idx_);
995 dst->SetCodeItemOffset(src.code_off_);
996 const char* shorty = dex_file.GetShorty(method_id.proto_idx_);
Brian Carlstromc74255f2011-09-11 22:47:39 -0700997 dst->SetShorty(intern_table_->InternStrong(shorty));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700998 dst->SetAccessFlags(src.access_flags_);
999 dst->SetReturnTypeIdx(dex_file.GetProtoId(method_id.proto_idx_).return_type_idx_);
Brian Carlstrom934486c2011-07-12 23:42:50 -07001000
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001001 dst->SetDexCacheStrings(klass->GetDexCache()->GetStrings());
1002 dst->SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes());
1003 dst->SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods());
1004 dst->SetDexCacheResolvedFields(klass->GetDexCache()->GetResolvedFields());
1005 dst->SetDexCacheCodeAndDirectMethods(klass->GetDexCache()->GetCodeAndDirectMethods());
1006 dst->SetDexCacheInitializedStaticStorage(klass->GetDexCache()->GetInitializedStaticStorage());
Brian Carlstrom9cc262e2011-08-28 12:45:30 -07001007
Brian Carlstrom934486c2011-07-12 23:42:50 -07001008 // TODO: check for finalize method
1009
Brian Carlstromf615a612011-07-23 12:50:34 -07001010 const DexFile::CodeItem* code_item = dex_file.GetCodeItem(src);
Brian Carlstrom934486c2011-07-12 23:42:50 -07001011 if (code_item != NULL) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001012 dst->SetNumRegisters(code_item->registers_size_);
1013 dst->SetNumIns(code_item->ins_size_);
1014 dst->SetNumOuts(code_item->outs_size_);
Brian Carlstrom934486c2011-07-12 23:42:50 -07001015 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001016 uint16_t num_args = Method::NumArgRegisters(shorty);
1017 if ((src.access_flags_ & kAccStatic) != 0) {
Brian Carlstrom934486c2011-07-12 23:42:50 -07001018 ++num_args;
1019 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001020 dst->SetNumRegisters(num_args);
Brian Carlstrom934486c2011-07-12 23:42:50 -07001021 // TODO: native methods
1022 }
1023}
1024
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001025void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001026 AppendToBootClassPath(dex_file, AllocDexCache(dex_file));
1027}
1028
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001029void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, DexCache* dex_cache) {
Brian Carlstrom69b15fb2011-09-03 12:25:21 -07001030 CHECK(dex_cache != NULL) << dex_file.GetLocation();
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001031 boot_class_path_.push_back(&dex_file);
Brian Carlstroma663ea52011-08-19 23:33:41 -07001032 RegisterDexFile(dex_file, dex_cache);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001033}
1034
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001035void ClassLinker::RegisterDexFile(const DexFile& dex_file) {
Brian Carlstroma663ea52011-08-19 23:33:41 -07001036 RegisterDexFile(dex_file, AllocDexCache(dex_file));
1037}
1038
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001039void ClassLinker::RegisterDexFile(const DexFile& dex_file, DexCache* dex_cache) {
Brian Carlstrom16192862011-09-12 17:50:06 -07001040 MutexLock mu(lock_);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -07001041 CHECK(dex_cache != NULL) << dex_file.GetLocation();
1042 CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation()));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001043 dex_files_.push_back(&dex_file);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001044 dex_caches_.push_back(dex_cache);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001045}
1046
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001047const DexFile& ClassLinker::FindDexFile(const DexCache* dex_cache) const {
Brian Carlstrom16192862011-09-12 17:50:06 -07001048 MutexLock mu(lock_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001049 for (size_t i = 0; i != dex_caches_.size(); ++i) {
1050 if (dex_caches_[i] == dex_cache) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001051 return *dex_files_[i];
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001052 }
1053 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -07001054 CHECK(false) << "Failed to find DexFile for DexCache " << dex_cache->GetLocation()->ToModifiedUtf8();
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001055 return *dex_files_[-1];
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001056}
1057
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001058DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
Brian Carlstrom16192862011-09-12 17:50:06 -07001059 MutexLock mu(lock_);
Brian Carlstromf615a612011-07-23 12:50:34 -07001060 for (size_t i = 0; i != dex_files_.size(); ++i) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001061 if (dex_files_[i] == &dex_file) {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001062 return dex_caches_[i];
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001063 }
1064 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -07001065 CHECK(false) << "Failed to find DexCache for DexFile " << dex_file.GetLocation();
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001066 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001067}
1068
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -07001069Class* ClassLinker::InitializePrimitiveClass(Class* primitive_class,
1070 const char* descriptor,
1071 Class::PrimitiveType type) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001072 // TODO: deduce one argument from the other
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -07001073 CHECK(primitive_class != NULL);
1074 primitive_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
1075 primitive_class->SetDescriptor(intern_table_->InternStrong(descriptor));
1076 primitive_class->SetPrimitiveType(type);
1077 primitive_class->SetStatus(Class::kStatusInitialized);
1078 bool success = InsertClass(descriptor, primitive_class);
1079 CHECK(success) << "InitPrimitiveClass(" << descriptor << ") failed";
1080 return primitive_class;
Carl Shapiro565f5072011-07-10 13:39:43 -07001081}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001082
Brian Carlstrombe977852011-07-19 14:54:54 -07001083// Create an array class (i.e. the class object for the array, not the
1084// array itself). "descriptor" looks like "[C" or "[[[[B" or
1085// "[Ljava/lang/String;".
1086//
1087// If "descriptor" refers to an array of primitives, look up the
1088// primitive type's internally-generated class object.
1089//
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -07001090// "class_loader" is the class loader of the class that's referring to
1091// us. It's used to ensure that we're looking for the element type in
1092// the right context. It does NOT become the class loader for the
1093// array class; that always comes from the base element class.
Brian Carlstrombe977852011-07-19 14:54:54 -07001094//
1095// Returns NULL with an exception raised on failure.
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001096Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor,
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001097 const ClassLoader* class_loader) {
1098 CHECK_EQ('[', descriptor[0]);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001099
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -07001100 // Identify the underlying component type
1101 Class* component_type = FindClass(descriptor.substr(1), class_loader);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001102 if (component_type == NULL) {
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -07001103 DCHECK(Thread::Current()->IsExceptionPending());
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001104 return NULL;
1105 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001106
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001107 // See if the component type is already loaded. Array classes are
1108 // always associated with the class loader of their underlying
1109 // element type -- an array of Strings goes with the loader for
1110 // java/lang/String -- so we need to look for it there. (The
1111 // caller should have checked for the existence of the class
1112 // before calling here, but they did so with *their* class loader,
1113 // not the component type's loader.)
1114 //
1115 // If we find it, the caller adds "loader" to the class' initiating
1116 // loader list, which should prevent us from going through this again.
1117 //
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001118 // This call is unnecessary if "loader" and "component_type->GetClassLoader()"
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001119 // are the same, because our caller (FindClass) just did the
1120 // lookup. (Even if we get this wrong we still have correct behavior,
1121 // because we effectively do this lookup again when we add the new
1122 // class to the hash table --- necessary because of possible races with
1123 // other threads.)
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001124 if (class_loader != component_type->GetClassLoader()) {
1125 Class* new_class = LookupClass(descriptor, component_type->GetClassLoader());
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001126 if (new_class != NULL) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001127 return new_class;
1128 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001129 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001130
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001131 // Fill out the fields in the Class.
1132 //
1133 // It is possible to execute some methods against arrays, because
1134 // all arrays are subclasses of java_lang_Object_, so we need to set
1135 // up a vtable. We can just point at the one in java_lang_Object_.
1136 //
1137 // Array classes are simple enough that we don't need to do a full
1138 // link step.
1139
1140 Class* new_class = NULL;
1141 if (!init_done_) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001142 // Classes that were hand created, ie not by FindSystemClass
Elliott Hughes418d20f2011-09-22 14:00:39 -07001143 if (descriptor == "[Ljava/lang/Class;") {
1144 new_class = GetClassRoot(kClassArrayClass);
1145 } else if (descriptor == "[Ljava/lang/Object;") {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001146 new_class = GetClassRoot(kObjectArrayClass);
1147 } else if (descriptor == "[C") {
1148 new_class = GetClassRoot(kCharArrayClass);
Elliott Hughesc1674ed2011-08-25 18:09:09 -07001149 } else if (descriptor == "[I") {
1150 new_class = GetClassRoot(kIntArrayClass);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001151 }
1152 }
1153 if (new_class == NULL) {
Brian Carlstrom4873d462011-08-21 15:23:39 -07001154 new_class = AllocClass(sizeof(Class));
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001155 if (new_class == NULL) {
1156 return NULL;
1157 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001158 new_class->SetComponentType(component_type);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001159 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001160 DCHECK(new_class->GetComponentType() != NULL);
Brian Carlstrom693267a2011-09-06 09:25:34 -07001161 if (new_class->GetDescriptor() != NULL) {
1162 DCHECK(new_class->GetDescriptor()->Equals(descriptor));
1163 } else {
Brian Carlstromc74255f2011-09-11 22:47:39 -07001164 new_class->SetDescriptor(intern_table_->InternStrong(descriptor.ToString().c_str()));
Brian Carlstrom693267a2011-09-06 09:25:34 -07001165 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001166 Class* java_lang_Object = GetClassRoot(kJavaLangObject);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001167 new_class->SetSuperClass(java_lang_Object);
1168 new_class->SetVTable(java_lang_Object->GetVTable());
1169 new_class->SetPrimitiveType(Class::kPrimNot);
1170 new_class->SetClassLoader(component_type->GetClassLoader());
1171 new_class->SetStatus(Class::kStatusInitialized);
1172 // don't need to set new_class->SetObjectSize(..)
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001173 // because Object::SizeOf delegates to Array::SizeOf
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001174
1175
1176 // All arrays have java/lang/Cloneable and java/io/Serializable as
1177 // interfaces. We need to set that up here, so that stuff like
1178 // "instanceof" works right.
1179 //
1180 // Note: The GC could run during the call to FindSystemClass,
1181 // so we need to make sure the class object is GC-valid while we're in
1182 // there. Do this by clearing the interface list so the GC will just
1183 // think that the entries are null.
1184
1185
1186 // Use the single, global copies of "interfaces" and "iftable"
1187 // (remember not to free them for arrays).
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001188 new_class->SetInterfaces(array_interfaces_);
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001189 new_class->SetIfTable(array_iftable_);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001190
1191 // Inherit access flags from the component type. Arrays can't be
1192 // used as a superclass or interface, so we want to add "final"
1193 // and remove "interface".
1194 //
1195 // Don't inherit any non-standard flags (e.g., kAccFinal)
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001196 // from component_type. We assume that the array class does not
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001197 // override finalize().
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001198 new_class->SetAccessFlags(((new_class->GetComponentType()->GetAccessFlags() &
1199 ~kAccInterface) | kAccFinal) & kAccJavaFlagsMask);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001200
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001201 if (InsertClass(descriptor, new_class)) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001202 return new_class;
1203 }
1204 // Another thread must have loaded the class after we
1205 // started but before we finished. Abandon what we've
1206 // done.
1207 //
1208 // (Yes, this happens.)
1209
1210 // Grab the winning class.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001211 Class* other_class = LookupClass(descriptor, component_type->GetClassLoader());
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001212 DCHECK(other_class != NULL);
1213 return other_class;
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001214}
1215
1216Class* ClassLinker::FindPrimitiveClass(char type) {
Carl Shapiro565f5072011-07-10 13:39:43 -07001217 switch (type) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001218 case 'B':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001219 return GetClassRoot(kPrimitiveByte);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001220 case 'C':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001221 return GetClassRoot(kPrimitiveChar);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001222 case 'D':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001223 return GetClassRoot(kPrimitiveDouble);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001224 case 'F':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001225 return GetClassRoot(kPrimitiveFloat);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001226 case 'I':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001227 return GetClassRoot(kPrimitiveInt);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001228 case 'J':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001229 return GetClassRoot(kPrimitiveLong);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001230 case 'S':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001231 return GetClassRoot(kPrimitiveShort);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001232 case 'Z':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001233 return GetClassRoot(kPrimitiveBoolean);
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001234 case 'V':
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001235 return GetClassRoot(kPrimitiveVoid);
Carl Shapiro744ad052011-08-06 15:53:36 -07001236 }
Elliott Hughesbd935992011-08-22 11:59:34 -07001237 std::string printable_type(PrintableChar(type));
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001238 ThrowNoClassDefFoundError("Not a primitive type: %s", printable_type.c_str());
Elliott Hughesbd935992011-08-22 11:59:34 -07001239 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001240}
1241
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001242bool ClassLinker::InsertClass(const StringPiece& descriptor, Class* klass) {
1243 size_t hash = StringPieceHash()(descriptor);
Brian Carlstrom16192862011-09-12 17:50:06 -07001244 MutexLock mu(lock_);
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001245 Table::iterator it = classes_.insert(std::make_pair(hash, klass));
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001246 return ((*it).second == klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001247}
1248
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001249Class* ClassLinker::LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader) {
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001250 size_t hash = StringPieceHash()(descriptor);
Brian Carlstrom16192862011-09-12 17:50:06 -07001251 MutexLock mu(lock_);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001252 typedef Table::const_iterator It; // TODO: C++0x auto
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001253 for (It it = classes_.find(hash), end = classes_.end(); it != end; ++it) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001254 Class* klass = it->second;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001255 if (klass->GetDescriptor()->Equals(descriptor) && klass->GetClassLoader() == class_loader) {
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001256 return klass;
1257 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001258 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001259 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001260}
1261
jeffhao98eacac2011-09-14 16:11:53 -07001262void ClassLinker::VerifyClass(Class* klass) {
1263 if (klass->IsVerified()) {
1264 return;
1265 }
1266
1267 CHECK_EQ(klass->GetStatus(), Class::kStatusResolved);
1268
1269 klass->SetStatus(Class::kStatusVerifying);
1270 if (!DexVerifier::VerifyClass(klass)) {
1271 LOG(ERROR) << "Verification failed on class "
1272 << klass->GetDescriptor()->ToModifiedUtf8();
1273 Object* exception = Thread::Current()->GetException();
Brian Carlstrom27ec9612011-09-19 20:20:38 -07001274 // CHECK(exception != NULL) << PrettyClass(klass);
1275 if (exception == NULL) {
1276 UNIMPLEMENTED(ERROR) << "null verification exception for " << PrettyClass(klass);
1277 } else {
1278 klass->SetVerifyErrorClass(exception->GetClass());
1279 }
jeffhao98eacac2011-09-14 16:11:53 -07001280 klass->SetStatus(Class::kStatusError);
1281 return;
1282 }
1283
1284 klass->SetStatus(Class::kStatusVerified);
1285}
1286
Brian Carlstrom25c33252011-09-18 15:58:35 -07001287bool ClassLinker::InitializeClass(Class* klass, bool can_run_clinit) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001288 CHECK(klass->GetStatus() == Class::kStatusResolved ||
jeffhao98eacac2011-09-14 16:11:53 -07001289 klass->GetStatus() == Class::kStatusVerified ||
Elliott Hughes005ab2e2011-09-11 17:15:31 -07001290 klass->GetStatus() == Class::kStatusInitializing ||
1291 klass->GetStatus() == Class::kStatusError)
Elliott Hughes54e7df12011-09-16 11:47:04 -07001292 << PrettyClass(klass) << " is " << klass->GetStatus();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001293
Carl Shapirob5573532011-07-12 18:22:59 -07001294 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001295
Brian Carlstrom25c33252011-09-18 15:58:35 -07001296 Method* clinit = NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001297 {
1298 ObjectLock lock(klass);
1299
1300 if (klass->GetStatus() < Class::kStatusVerified) {
1301 if (klass->IsErroneous()) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001302 ThrowEarlierClassFailure(klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001303 return false;
1304 }
1305
jeffhao98eacac2011-09-14 16:11:53 -07001306 VerifyClass(klass);
1307 if (klass->GetStatus() != Class::kStatusVerified) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001308 return false;
1309 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001310 }
1311
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001312 if (klass->GetStatus() == Class::kStatusInitialized) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001313 return true;
1314 }
1315
Brian Carlstrom25c33252011-09-18 15:58:35 -07001316 clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
1317 if (clinit != NULL && !can_run_clinit) {
1318 // if the class has a <clinit>, don't bother going to initializing
1319 return false;
1320 }
1321
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001322 while (klass->GetStatus() == Class::kStatusInitializing) {
Elliott Hughes005ab2e2011-09-11 17:15:31 -07001323 // We caught somebody else in the act; was it us?
Elliott Hughesdcc24742011-09-07 14:02:44 -07001324 if (klass->GetClinitThreadId() == self->GetTid()) {
Elliott Hughes005ab2e2011-09-11 17:15:31 -07001325 // Yes. That's fine.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001326 return true;
1327 }
1328
1329 CHECK(!self->IsExceptionPending());
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001330 lock.Wait();
1331 CHECK(!self->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001332
1333 // When we wake up, repeat the test for init-in-progress. If
1334 // there's an exception pending (only possible if
1335 // "interruptShouldThrow" was set), bail out.
1336 if (self->IsExceptionPending()) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001337 self->ThrowNewException("Ljava/lang/ExceptionInInitializerError;",
1338 "Exception %s thrown while initializing class %s",
1339 PrettyTypeOf(self->GetException()).c_str(),
1340 PrettyDescriptor(klass->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001341 klass->SetStatus(Class::kStatusError);
1342 return false;
1343 }
1344 if (klass->GetStatus() == Class::kStatusInitializing) {
1345 continue;
1346 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001347 DCHECK(klass->GetStatus() == Class::kStatusInitialized ||
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001348 klass->GetStatus() == Class::kStatusError);
1349 if (klass->IsErroneous()) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001350 // The caller wants an exception, but it was thrown in a
1351 // different thread. Synthesize one here.
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001352 self->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;",
1353 "<clinit> failed for class %s; see exception in other thread",
1354 PrettyDescriptor(klass->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001355 return false;
1356 }
1357 return true; // otherwise, initialized
1358 }
1359
1360 // see if we failed previously
1361 if (klass->IsErroneous()) {
1362 // might be wise to unlock before throwing; depends on which class
1363 // it is that we have locked
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001364 ThrowEarlierClassFailure(klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001365 return false;
1366 }
1367
1368 if (!ValidateSuperClassDescriptors(klass)) {
1369 klass->SetStatus(Class::kStatusError);
1370 return false;
1371 }
1372
Brian Carlstrom25c33252011-09-18 15:58:35 -07001373 DCHECK_LT(klass->GetStatus(), Class::kStatusInitializing);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001374
Elliott Hughesdcc24742011-09-07 14:02:44 -07001375 klass->SetClinitThreadId(self->GetTid());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001376 klass->SetStatus(Class::kStatusInitializing);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001377 }
1378
Brian Carlstrom25c33252011-09-18 15:58:35 -07001379 if (!InitializeSuperClass(klass, can_run_clinit)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001380 return false;
1381 }
1382
1383 InitializeStaticFields(klass);
1384
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001385 if (clinit != NULL) {
Elliott Hughesf5ecf062011-09-06 17:37:59 -07001386 clinit->Invoke(self, NULL, NULL, NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001387 }
1388
1389 {
1390 ObjectLock lock(klass);
1391
1392 if (self->IsExceptionPending()) {
1393 klass->SetStatus(Class::kStatusError);
1394 } else {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07001395 ++Runtime::Current()->GetStats()->class_init_count;
1396 ++self->GetStats()->class_init_count;
1397 // TODO: class_init_time_ns
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001398 klass->SetStatus(Class::kStatusInitialized);
1399 }
1400 lock.NotifyAll();
1401 }
1402
1403 return true;
1404}
1405
1406bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
1407 if (klass->IsInterface()) {
1408 return true;
1409 }
1410 // begin with the methods local to the superclass
1411 if (klass->HasSuperClass() &&
1412 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
1413 const Class* super = klass->GetSuperClass();
1414 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
Elliott Hughesf4c21c92011-08-19 17:31:31 -07001415 const Method* method = super->GetVirtualMethod(i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001416 if (method != super->GetVirtualMethod(i) &&
1417 !HasSameMethodDescriptorClasses(method, super, klass)) {
Elliott Hughes4681c802011-09-25 18:04:37 -07001418 klass->DumpClass(std::cerr, Class::kDumpClassFullDetail);
1419
1420 ThrowLinkageError("Class %s method %s resolves differently in superclass %s", PrettyDescriptor(klass->GetDescriptor()).c_str(), PrettyMethod(method).c_str(), PrettyDescriptor(super->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001421 return false;
1422 }
1423 }
1424 }
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001425 for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
1426 InterfaceEntry* interface_entry = klass->GetIfTable()->Get(i);
1427 Class* interface = interface_entry->GetInterface();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001428 if (klass->GetClassLoader() != interface->GetClassLoader()) {
1429 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001430 const Method* method = interface_entry->GetMethodArray()->Get(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001431 if (!HasSameMethodDescriptorClasses(method, interface,
Brian Carlstrom27ec9612011-09-19 20:20:38 -07001432 method->GetDeclaringClass())) {
Elliott Hughes4681c802011-09-25 18:04:37 -07001433 klass->DumpClass(std::cerr, Class::kDumpClassFullDetail);
1434
1435 ThrowLinkageError("Class %s method %s resolves differently in interface %s", PrettyDescriptor(method->GetDeclaringClass()->GetDescriptor()).c_str(), PrettyMethod(method).c_str(), PrettyDescriptor(interface->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001436 return false;
1437 }
1438 }
1439 }
1440 }
1441 return true;
1442}
1443
1444bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
Brian Carlstrom934486c2011-07-12 23:42:50 -07001445 const Class* klass1,
1446 const Class* klass2) {
Elliott Hughes4681c802011-09-25 18:04:37 -07001447 if (method->IsMiranda()) { return true; }
Brian Carlstrom27ec9612011-09-19 20:20:38 -07001448 const DexFile& dex_file = FindDexFile(method->GetDeclaringClass()->GetDexCache());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001449 const DexFile::ProtoId& proto_id = dex_file.GetProtoId(method->GetProtoIdx());
Brian Carlstromf615a612011-07-23 12:50:34 -07001450 DexFile::ParameterIterator *it;
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001451 for (it = dex_file.GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001452 const char* descriptor = it->GetDescriptor();
1453 if (descriptor == NULL) {
1454 break;
1455 }
1456 if (descriptor[0] == 'L' || descriptor[0] == '[') {
1457 // Found a non-primitive type.
1458 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
1459 return false;
1460 }
1461 }
1462 }
1463 // Check the return type
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001464 const char* descriptor = dex_file.GetReturnTypeDescriptor(proto_id);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001465 if (descriptor[0] == 'L' || descriptor[0] == '[') {
1466 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
1467 return false;
1468 }
1469 }
1470 return true;
1471}
1472
1473// Returns true if classes referenced by the descriptor are the
1474// same classes in klass1 as they are in klass2.
1475bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
Brian Carlstrom934486c2011-07-12 23:42:50 -07001476 const Class* klass1,
1477 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001478 CHECK(descriptor != NULL);
1479 CHECK(klass1 != NULL);
1480 CHECK(klass2 != NULL);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001481 Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001482 // TODO: found1 == NULL
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001483 Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001484 // TODO: found2 == NULL
1485 // TODO: lookup found1 in initiating loader list
1486 if (found1 == NULL || found2 == NULL) {
Carl Shapirob5573532011-07-12 18:22:59 -07001487 Thread::Current()->ClearException();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001488 if (found1 == found2) {
1489 return true;
1490 } else {
1491 return false;
1492 }
1493 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001494 return true;
1495}
1496
Brian Carlstrom25c33252011-09-18 15:58:35 -07001497bool ClassLinker::InitializeSuperClass(Class* klass, bool can_run_clinit) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001498 CHECK(klass != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001499 if (!klass->IsInterface() && klass->HasSuperClass()) {
1500 Class* super_class = klass->GetSuperClass();
1501 if (super_class->GetStatus() != Class::kStatusInitialized) {
1502 CHECK(!super_class->IsInterface());
Elliott Hughes5f791332011-09-15 17:45:30 -07001503 Thread* self = Thread::Current();
1504 klass->MonitorEnter(self);
Brian Carlstrom25c33252011-09-18 15:58:35 -07001505 bool super_initialized = InitializeClass(super_class, can_run_clinit);
Elliott Hughes5f791332011-09-15 17:45:30 -07001506 klass->MonitorExit(self);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001507 // TODO: check for a pending exception
1508 if (!super_initialized) {
Brian Carlstrom25c33252011-09-18 15:58:35 -07001509 if (!can_run_clinit) {
1510 // Don't set status to error when we can't run <clinit>.
1511 CHECK_EQ(klass->GetStatus(), Class::kStatusInitializing);
1512 klass->SetStatus(Class::kStatusVerified);
1513 return false;
1514 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001515 klass->SetStatus(Class::kStatusError);
1516 klass->NotifyAll();
1517 return false;
1518 }
1519 }
1520 }
1521 return true;
1522}
1523
Brian Carlstrom25c33252011-09-18 15:58:35 -07001524bool ClassLinker::EnsureInitialized(Class* c, bool can_run_clinit) {
Elliott Hughesf4c21c92011-08-19 17:31:31 -07001525 CHECK(c != NULL);
1526 if (c->IsInitialized()) {
1527 return true;
1528 }
1529
Elliott Hughes5f791332011-09-15 17:45:30 -07001530 Thread* self = Thread::Current();
Elliott Hughes4681c802011-09-25 18:04:37 -07001531 ScopedThreadStateChange tsc(self, Thread::kRunnable);
1532 LOG(INFO) << "initializing " << PrettyClass(c) << " from " << *self;
Elliott Hughes5f791332011-09-15 17:45:30 -07001533 c->MonitorEnter(self);
Brian Carlstrom25c33252011-09-18 15:58:35 -07001534 InitializeClass(c, can_run_clinit);
Elliott Hughes5f791332011-09-15 17:45:30 -07001535 c->MonitorExit(self);
1536 return !self->IsExceptionPending();
Elliott Hughesf4c21c92011-08-19 17:31:31 -07001537}
1538
Brian Carlstromb9edb842011-08-28 16:31:06 -07001539StaticStorageBase* ClassLinker::InitializeStaticStorageFromCode(uint32_t type_idx,
1540 const Method* referrer) {
Brian Carlstrom1caa2c22011-08-28 13:02:33 -07001541 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1542 Class* klass = class_linker->ResolveType(type_idx, referrer);
1543 if (klass == NULL) {
Ian Rogerscbba6ac2011-09-22 16:28:37 -07001544 CHECK(Thread::Current()->IsExceptionPending());
1545 return NULL; // Failure - Indicate to caller to deliver exception
Brian Carlstrom1caa2c22011-08-28 13:02:33 -07001546 }
Brian Carlstrom193a44d2011-09-04 12:01:42 -07001547 // If we are the <clinit> of this class, just return our storage.
1548 //
1549 // Do not set the DexCache InitializedStaticStorage, since that
1550 // implies <clinit> has finished running.
1551 if (klass == referrer->GetDeclaringClass() && referrer->GetName()->Equals("<clinit>")) {
1552 return klass;
1553 }
Brian Carlstrom25c33252011-09-18 15:58:35 -07001554 if (!class_linker->EnsureInitialized(klass, true)) {
Brian Carlstrom1caa2c22011-08-28 13:02:33 -07001555 CHECK(Thread::Current()->IsExceptionPending());
Ian Rogerscbba6ac2011-09-22 16:28:37 -07001556 return NULL; // Failure - Indicate to caller to deliver exception
Brian Carlstrom1caa2c22011-08-28 13:02:33 -07001557 }
Brian Carlstrom848a4b32011-09-04 11:29:27 -07001558 referrer->GetDexCacheInitializedStaticStorage()->Set(type_idx, klass);
Brian Carlstrom1caa2c22011-08-28 13:02:33 -07001559 return klass;
1560}
1561
Elliott Hughes5fe594f2011-09-08 12:33:17 -07001562void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
1563 Class* c, std::map<int, Field*>& field_map) {
1564 const ClassLoader* cl = c->GetClassLoader();
1565 const byte* class_data = dex_file.GetClassData(dex_class_def);
1566 DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data);
1567 uint32_t last_idx = 0;
1568 for (size_t i = 0; i < header.static_fields_size_; ++i) {
1569 DexFile::Field dex_field;
1570 dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx);
1571 field_map[i] = ResolveField(dex_file, dex_field.field_idx_, c->GetDexCache(), cl, true);
1572 }
1573}
1574
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001575void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001576 size_t num_static_fields = klass->NumStaticFields();
1577 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001578 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001579 }
Brian Carlstromf615a612011-07-23 12:50:34 -07001580 DexCache* dex_cache = klass->GetDexCache();
Brian Carlstrom4873d462011-08-21 15:23:39 -07001581 // TODO: this seems like the wrong check. do we really want !IsPrimitive && !IsArray?
Brian Carlstromf615a612011-07-23 12:50:34 -07001582 if (dex_cache == NULL) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001583 return;
1584 }
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001585 const std::string descriptor(klass->GetDescriptor()->ToModifiedUtf8());
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001586 const DexFile& dex_file = FindDexFile(dex_cache);
1587 const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
Brian Carlstromf615a612011-07-23 12:50:34 -07001588 CHECK(dex_class_def != NULL);
Elliott Hughes5fe594f2011-09-08 12:33:17 -07001589
1590 // We reordered the fields, so we need to be able to map the field indexes to the right fields.
1591 std::map<int, Field*> field_map;
1592 ConstructFieldMap(dex_file, *dex_class_def, klass, field_map);
1593
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001594 const byte* addr = dex_file.GetEncodedArray(*dex_class_def);
Elliott Hughesf4c21c92011-08-19 17:31:31 -07001595 if (addr == NULL) {
1596 // All this class' static fields have default values.
1597 return;
1598 }
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001599 size_t array_size = DecodeUnsignedLeb128(&addr);
1600 for (size_t i = 0; i < array_size; ++i) {
Elliott Hughes5fe594f2011-09-08 12:33:17 -07001601 Field* field = field_map[i];
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001602 JValue value;
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001603 DexFile::ValueType type = dex_file.ReadEncodedValue(&addr, &value);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001604 switch (type) {
Brian Carlstromf615a612011-07-23 12:50:34 -07001605 case DexFile::kByte:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001606 field->SetByte(NULL, value.b);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001607 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001608 case DexFile::kShort:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001609 field->SetShort(NULL, value.s);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001610 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001611 case DexFile::kChar:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001612 field->SetChar(NULL, value.c);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001613 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001614 case DexFile::kInt:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001615 field->SetInt(NULL, value.i);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001616 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001617 case DexFile::kLong:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001618 field->SetLong(NULL, value.j);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001619 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001620 case DexFile::kFloat:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001621 field->SetFloat(NULL, value.f);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001622 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001623 case DexFile::kDouble:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001624 field->SetDouble(NULL, value.d);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001625 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001626 case DexFile::kString: {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001627 uint32_t string_idx = value.i;
Elliott Hughescf4c6c42011-09-01 15:16:42 -07001628 const String* resolved = ResolveString(dex_file, string_idx, klass->GetDexCache());
Brian Carlstrom4873d462011-08-21 15:23:39 -07001629 field->SetObject(NULL, resolved);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001630 break;
1631 }
Brian Carlstromf615a612011-07-23 12:50:34 -07001632 case DexFile::kBoolean:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001633 field->SetBoolean(NULL, value.z);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001634 break;
Brian Carlstromf615a612011-07-23 12:50:34 -07001635 case DexFile::kNull:
Brian Carlstrom4873d462011-08-21 15:23:39 -07001636 field->SetObject(NULL, value.l);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001637 break;
1638 default:
Carl Shapiro606258b2011-07-09 16:09:09 -07001639 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001640 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001641 }
1642}
1643
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001644bool ClassLinker::LinkClass(Class* klass) {
1645 CHECK_EQ(Class::kStatusLoaded, klass->GetStatus());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001646 if (!LinkSuperClass(klass)) {
1647 return false;
1648 }
1649 if (!LinkMethods(klass)) {
1650 return false;
1651 }
1652 if (!LinkInstanceFields(klass)) {
1653 return false;
1654 }
Brian Carlstrom4873d462011-08-21 15:23:39 -07001655 if (!LinkStaticFields(klass)) {
1656 return false;
1657 }
1658 CreateReferenceInstanceOffsets(klass);
1659 CreateReferenceStaticOffsets(klass);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001660 CHECK_EQ(Class::kStatusLoaded, klass->GetStatus());
1661 klass->SetStatus(Class::kStatusResolved);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001662 return true;
1663}
1664
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001665bool ClassLinker::LoadSuperAndInterfaces(Class* klass, const DexFile& dex_file) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001666 CHECK_EQ(Class::kStatusIdx, klass->GetStatus());
1667 if (klass->GetSuperClassTypeIdx() != DexFile::kDexNoIndex) {
1668 Class* super_class = ResolveType(dex_file, klass->GetSuperClassTypeIdx(), klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001669 if (super_class == NULL) {
Brian Carlstrom65ca0772011-09-24 16:03:08 -07001670 DCHECK(Thread::Current()->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001671 return false;
1672 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001673 klass->SetSuperClass(super_class);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001674 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001675 for (size_t i = 0; i < klass->NumInterfaces(); ++i) {
1676 uint32_t idx = klass->GetInterfacesTypeIdx()->Get(i);
Elliott Hughese555dc02011-09-25 10:46:35 -07001677 Class* interface = ResolveType(dex_file, idx, klass);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001678 klass->SetInterface(i, interface);
1679 if (interface == NULL) {
Elliott Hughese555dc02011-09-25 10:46:35 -07001680 DCHECK(Thread::Current()->IsExceptionPending());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001681 return false;
1682 }
1683 // Verify
1684 if (!klass->CanAccess(interface)) {
Elliott Hughese555dc02011-09-25 10:46:35 -07001685 // TODO: the RI seemed to ignore this in my testing.
1686 Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;",
1687 "Interface %s implemented by class %s is inaccessible",
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001688 PrettyDescriptor(interface->GetDescriptor()).c_str(),
1689 PrettyDescriptor(klass->GetDescriptor()).c_str());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001690 return false;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001691 }
1692 }
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07001693 // Mark the class as loaded.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001694 klass->SetStatus(Class::kStatusLoaded);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001695 return true;
1696}
1697
1698bool ClassLinker::LinkSuperClass(Class* klass) {
1699 CHECK(!klass->IsPrimitive());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001700 Class* super = klass->GetSuperClass();
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001701 if (klass->GetDescriptor()->Equals("Ljava/lang/Object;")) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001702 if (super != NULL) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001703 Thread::Current()->ThrowNewException("Ljava/lang/ClassFormatError;",
1704 "java.lang.Object must not have a superclass");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001705 return false;
1706 }
1707 // TODO: clear finalize attribute
1708 return true;
1709 }
1710 if (super == NULL) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001711 ThrowLinkageError("No superclass defined for class %s",
1712 PrettyDescriptor(klass->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001713 return false;
1714 }
1715 // Verify
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001716 if (super->IsFinal() || super->IsInterface()) {
1717 Thread::Current()->ThrowNewException("Ljava/lang/IncompatibleClassChangeError;",
Elliott Hughese555dc02011-09-25 10:46:35 -07001718 "Superclass %s of %s is %s",
1719 PrettyDescriptor(super->GetDescriptor()).c_str(),
1720 PrettyDescriptor(klass->GetDescriptor()).c_str(),
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001721 super->IsFinal() ? "declared final" : "an interface");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001722 return false;
1723 }
1724 if (!klass->CanAccess(super)) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001725 Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;",
Elliott Hughese555dc02011-09-25 10:46:35 -07001726 "Superclass %s is inaccessible by %s",
1727 PrettyDescriptor(super->GetDescriptor()).c_str(),
1728 PrettyDescriptor(klass->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001729 return false;
1730 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001731#ifndef NDEBUG
1732 // Ensure super classes are fully resolved prior to resolving fields..
1733 while (super != NULL) {
Elliott Hughes5fe594f2011-09-08 12:33:17 -07001734 CHECK(super->IsResolved());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001735 super = super->GetSuperClass();
1736 }
1737#endif
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001738 return true;
1739}
1740
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001741// Populate the class vtable and itable. Compute return type indices.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001742bool ClassLinker::LinkMethods(Class* klass) {
1743 if (klass->IsInterface()) {
1744 // No vtable.
1745 size_t count = klass->NumVirtualMethods();
1746 if (!IsUint(16, count)) {
Elliott Hughese555dc02011-09-25 10:46:35 -07001747 ThrowClassFormatError("Too many methods on interface: %d", count);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001748 return false;
1749 }
Carl Shapiro565f5072011-07-10 13:39:43 -07001750 for (size_t i = 0; i < count; ++i) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001751 klass->GetVirtualMethodDuringLinking(i)->SetMethodIndex(i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001752 }
jeffhaobdb76512011-09-07 11:43:16 -07001753 // Link interface method tables
1754 LinkInterfaceMethods(klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001755 } else {
1756 // Link virtual method tables
1757 LinkVirtualMethods(klass);
1758
1759 // Link interface method tables
1760 LinkInterfaceMethods(klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001761 }
1762 return true;
1763}
1764
1765bool ClassLinker::LinkVirtualMethods(Class* klass) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001766 if (klass->HasSuperClass()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001767 uint32_t max_count = klass->NumVirtualMethods() + klass->GetSuperClass()->GetVTable()->GetLength();
1768 size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength();
Brian Carlstrom4a96b602011-07-26 16:40:23 -07001769 CHECK_LE(actual_count, max_count);
Brian Carlstroma40f9bc2011-07-26 21:26:07 -07001770 // TODO: do not assign to the vtable field until it is fully constructed.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001771 ObjectArray<Method>* vtable = klass->GetSuperClass()->GetVTable()->CopyOf(max_count);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001772 // See if any of our virtual methods override the superclass.
1773 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001774 Method* local_method = klass->GetVirtualMethodDuringLinking(i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001775 size_t j = 0;
Brian Carlstrom4a96b602011-07-26 16:40:23 -07001776 for (; j < actual_count; ++j) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001777 Method* super_method = vtable->Get(j);
Carl Shapiro8860c0e2011-08-04 17:36:16 -07001778 if (local_method->HasSameNameAndDescriptor(super_method)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001779 // Verify
1780 if (super_method->IsFinal()) {
Elliott Hughese555dc02011-09-25 10:46:35 -07001781 ThrowLinkageError("Method %s.%s overrides final method in class %s",
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001782 PrettyDescriptor(klass->GetDescriptor()).c_str(),
1783 local_method->GetName()->ToModifiedUtf8().c_str(),
1784 PrettyDescriptor(super_method->GetDeclaringClass()->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001785 return false;
1786 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001787 vtable->Set(j, local_method);
1788 local_method->SetMethodIndex(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001789 break;
1790 }
1791 }
Brian Carlstrom4a96b602011-07-26 16:40:23 -07001792 if (j == actual_count) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001793 // Not overriding, append.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001794 vtable->Set(actual_count, local_method);
1795 local_method->SetMethodIndex(actual_count);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001796 actual_count += 1;
1797 }
1798 }
1799 if (!IsUint(16, actual_count)) {
Elliott Hughese555dc02011-09-25 10:46:35 -07001800 ThrowClassFormatError("Too many methods defined on class: %d", actual_count);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001801 return false;
1802 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001803 // Shrink vtable if possible
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001804 CHECK_LE(actual_count, max_count);
1805 if (actual_count < max_count) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001806 vtable = vtable->CopyOf(actual_count);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001807 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001808 klass->SetVTable(vtable);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001809 } else {
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001810 CHECK(klass->GetDescriptor()->Equals("Ljava/lang/Object;"));
Brian Carlstroma40f9bc2011-07-26 21:26:07 -07001811 uint32_t num_virtual_methods = klass->NumVirtualMethods();
Brian Carlstroma40f9bc2011-07-26 21:26:07 -07001812 if (!IsUint(16, num_virtual_methods)) {
Elliott Hughese555dc02011-09-25 10:46:35 -07001813 ThrowClassFormatError("Too many methods: %d", num_virtual_methods);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001814 return false;
1815 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001816 ObjectArray<Method>* vtable = AllocObjectArray<Method>(num_virtual_methods);
Brian Carlstroma40f9bc2011-07-26 21:26:07 -07001817 for (size_t i = 0; i < num_virtual_methods; ++i) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001818 Method* virtual_method = klass->GetVirtualMethodDuringLinking(i);
1819 vtable->Set(i, virtual_method);
1820 virtual_method->SetMethodIndex(i & 0xFFFF);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001821 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001822 klass->SetVTable(vtable);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001823 }
1824 return true;
1825}
1826
1827bool ClassLinker::LinkInterfaceMethods(Class* klass) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001828 size_t super_ifcount;
1829 if (klass->HasSuperClass()) {
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001830 super_ifcount = klass->GetSuperClass()->GetIfTableCount();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001831 } else {
1832 super_ifcount = 0;
1833 }
Brian Carlstrom913af1b2011-07-23 21:41:13 -07001834 size_t ifcount = super_ifcount;
1835 ifcount += klass->NumInterfaces();
1836 for (size_t i = 0; i < klass->NumInterfaces(); i++) {
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001837 ifcount += klass->GetInterface(i)->GetIfTableCount();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001838 }
Brian Carlstrom913af1b2011-07-23 21:41:13 -07001839 if (ifcount == 0) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001840 // TODO: enable these asserts with klass status validation
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001841 // DCHECK(klass->GetIfTableCount() == 0);
1842 // DCHECK(klass->GetIfTable() == NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001843 return true;
1844 }
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001845 ObjectArray<InterfaceEntry>* iftable = AllocObjectArray<InterfaceEntry>(ifcount);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001846 if (super_ifcount != 0) {
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001847 ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
1848 for (size_t i = 0; i < super_ifcount; i++) {
1849 iftable->Set(i, AllocInterfaceEntry(super_iftable->Get(i)->GetInterface()));
1850 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001851 }
1852 // Flatten the interface inheritance hierarchy.
1853 size_t idx = super_ifcount;
Brian Carlstrom913af1b2011-07-23 21:41:13 -07001854 for (size_t i = 0; i < klass->NumInterfaces(); i++) {
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001855 Class* interface = klass->GetInterface(i);
1856 DCHECK(interface != NULL);
1857 if (!interface->IsInterface()) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001858 Thread::Current()->ThrowNewException("Ljava/lang/IncompatibleClassChangeError;",
1859 "Class %s implements non-interface class %s",
1860 PrettyDescriptor(klass->GetDescriptor()).c_str(),
1861 PrettyDescriptor(interface->GetDescriptor()).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001862 return false;
1863 }
Elliott Hughes4681c802011-09-25 18:04:37 -07001864 // Add this interface.
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001865 iftable->Set(idx++, AllocInterfaceEntry(interface));
Elliott Hughes4681c802011-09-25 18:04:37 -07001866 // Add this interface's superinterfaces.
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001867 for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
1868 iftable->Set(idx++, AllocInterfaceEntry(interface->GetIfTable()->Get(j)->GetInterface()));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001869 }
1870 }
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001871 klass->SetIfTable(iftable);
Brian Carlstrom913af1b2011-07-23 21:41:13 -07001872 CHECK_EQ(idx, ifcount);
Elliott Hughes4681c802011-09-25 18:04:37 -07001873
1874 // If we're an interface, we don't need the vtable pointers, so we're done.
1875 if (klass->IsInterface() /*|| super_ifcount == ifcount*/) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001876 return true;
1877 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001878 std::vector<Method*> miranda_list;
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001879 for (size_t i = 0; i < ifcount; ++i) {
1880 InterfaceEntry* interface_entry = iftable->Get(i);
1881 Class* interface = interface_entry->GetInterface();
1882 ObjectArray<Method>* method_array = AllocObjectArray<Method>(interface->NumVirtualMethods());
1883 interface_entry->SetMethodArray(method_array);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001884 ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001885 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
1886 Method* interface_method = interface->GetVirtualMethod(j);
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001887 int32_t k;
Elliott Hughes4681c802011-09-25 18:04:37 -07001888 // For each method listed in the interface's method list, find the
1889 // matching method in our class's method list. We want to favor the
1890 // subclass over the superclass, which just requires walking
1891 // back from the end of the vtable. (This only matters if the
1892 // superclass defines a private method and this class redefines
1893 // it -- otherwise it would use the same vtable slot. In .dex files
1894 // those don't end up in the virtual method table, so it shouldn't
1895 // matter which direction we go. We walk it backward anyway.)
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001896 for (k = vtable->GetLength() - 1; k >= 0; --k) {
1897 Method* vtable_method = vtable->Get(k);
Carl Shapiro8860c0e2011-08-04 17:36:16 -07001898 if (interface_method->HasSameNameAndDescriptor(vtable_method)) {
1899 if (!vtable_method->IsPublic()) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07001900 Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;",
1901 "Implementation not public: %s", PrettyMethod(vtable_method).c_str());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001902 return false;
1903 }
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001904 method_array->Set(j, vtable_method);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001905 break;
1906 }
1907 }
1908 if (k < 0) {
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001909 Method* miranda_method = NULL;
Elliott Hughes4681c802011-09-25 18:04:37 -07001910 for (size_t mir = 0; mir < miranda_list.size(); mir++) {
1911 if (miranda_list[mir]->HasSameNameAndDescriptor(interface_method)) {
1912 miranda_method = miranda_list[mir];
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001913 break;
1914 }
1915 }
Elliott Hughes4681c802011-09-25 18:04:37 -07001916 if (miranda_method == NULL) {
1917 // point the interface table at a phantom slot
1918 miranda_method = AllocMethod();
1919 memcpy(miranda_method, interface_method, sizeof(Method));
1920 miranda_list.push_back(miranda_method);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001921 }
Elliott Hughes4681c802011-09-25 18:04:37 -07001922 method_array->Set(j, miranda_method);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001923 }
1924 }
1925 }
Elliott Hughes4681c802011-09-25 18:04:37 -07001926 if (!miranda_list.empty()) {
Brian Carlstrom913af1b2011-07-23 21:41:13 -07001927 int old_method_count = klass->NumVirtualMethods();
Elliott Hughes4681c802011-09-25 18:04:37 -07001928 int new_method_count = old_method_count + miranda_list.size();
Brian Carlstrom27ec9612011-09-19 20:20:38 -07001929 klass->SetVirtualMethods((old_method_count == 0)
1930 ? AllocObjectArray<Method>(new_method_count)
1931 : klass->GetVirtualMethods()->CopyOf(new_method_count));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001932
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001933 ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
1934 CHECK(vtable != NULL);
1935 int old_vtable_count = vtable->GetLength();
Elliott Hughes4681c802011-09-25 18:04:37 -07001936 int new_vtable_count = old_vtable_count + miranda_list.size();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001937 vtable = vtable->CopyOf(new_vtable_count);
Elliott Hughes4681c802011-09-25 18:04:37 -07001938 for (size_t i = 0; i < miranda_list.size(); ++i) {
1939 Method* meth = miranda_list[i]; //AllocMethod();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001940 // TODO: this shouldn't be a memcpy
Elliott Hughes4681c802011-09-25 18:04:37 -07001941 //memcpy(meth, miranda_list[i], sizeof(Method));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001942 meth->SetDeclaringClass(klass);
1943 meth->SetAccessFlags(meth->GetAccessFlags() | kAccMiranda);
1944 meth->SetMethodIndex(0xFFFF & (old_vtable_count + i));
Brian Carlstrom913af1b2011-07-23 21:41:13 -07001945 klass->SetVirtualMethod(old_method_count + i, meth);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001946 vtable->Set(old_vtable_count + i, meth);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001947 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001948 // TODO: do not assign to the vtable field until it is fully constructed.
1949 klass->SetVTable(vtable);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001950 }
Elliott Hughes4681c802011-09-25 18:04:37 -07001951
1952 ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
1953 for (int i = 0; i < vtable->GetLength(); ++i) {
1954 CHECK(vtable->Get(i) != NULL);
1955 }
1956
1957// klass->DumpClass(std::cerr, Class::kDumpClassFullDetail);
1958
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001959 return true;
1960}
1961
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001962bool ClassLinker::LinkInstanceFields(Class* klass) {
Brian Carlstrom4873d462011-08-21 15:23:39 -07001963 CHECK(klass != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001964 return LinkFields(klass, true);
Brian Carlstrom4873d462011-08-21 15:23:39 -07001965}
1966
1967bool ClassLinker::LinkStaticFields(Class* klass) {
1968 CHECK(klass != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001969 size_t allocated_class_size = klass->GetClassSize();
1970 bool success = LinkFields(klass, false);
1971 CHECK_EQ(allocated_class_size, klass->GetClassSize());
Brian Carlstrom4873d462011-08-21 15:23:39 -07001972 return success;
1973}
1974
Brian Carlstromdbc05252011-09-09 01:59:59 -07001975struct LinkFieldsComparator {
1976 bool operator()(const Field* field1, const Field* field2){
1977
1978 // First come reference fields, then 64-bit, and finally 32-bit
1979 const Class* type1 = field1->GetTypeDuringLinking();
1980 const Class* type2 = field2->GetTypeDuringLinking();
1981 bool isPrimitive1 = type1 != NULL && type1->IsPrimitive();
1982 bool isPrimitive2 = type2 != NULL && type2->IsPrimitive();
1983 bool is64bit1 = isPrimitive1 && (type1->IsPrimitiveLong() || type1->IsPrimitiveDouble());
1984 bool is64bit2 = isPrimitive2 && (type2->IsPrimitiveLong() || type2->IsPrimitiveDouble());
1985 int order1 = (!isPrimitive1 ? 0 : (is64bit1 ? 1 : 2));
1986 int order2 = (!isPrimitive2 ? 0 : (is64bit2 ? 1 : 2));
1987 if (order1 != order2) {
1988 return order1 < order2;
1989 }
1990
1991 // same basic group? then sort by string.
1992 std::string name1 = field1->GetName()->ToModifiedUtf8();
1993 std::string name2 = field2->GetName()->ToModifiedUtf8();
1994 return name1 < name2;
1995 }
1996};
1997
Elliott Hughes5fe594f2011-09-08 12:33:17 -07001998bool ClassLinker::LinkFields(Class* klass, bool instance) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001999 size_t num_fields =
2000 instance ? klass->NumInstanceFields() : klass->NumStaticFields();
2001
2002 ObjectArray<Field>* fields =
2003 instance ? klass->GetIFields() : klass->GetSFields();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002004
2005 // Initialize size and field_offset
Brian Carlstrom693267a2011-09-06 09:25:34 -07002006 size_t size;
2007 MemberOffset field_offset(0);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002008 if (instance) {
2009 Class* super_class = klass->GetSuperClass();
2010 if (super_class != NULL) {
Elliott Hughes5fe594f2011-09-08 12:33:17 -07002011 CHECK(super_class->IsResolved());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002012 field_offset = MemberOffset(super_class->GetObjectSize());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002013 }
2014 size = field_offset.Uint32Value();
2015 } else {
2016 size = klass->GetClassSize();
Brian Carlstrom693267a2011-09-06 09:25:34 -07002017 field_offset = Class::FieldsOffset();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002018 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002019
Brian Carlstromdbc05252011-09-09 01:59:59 -07002020 CHECK_EQ(num_fields == 0, fields == NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002021
Brian Carlstromdbc05252011-09-09 01:59:59 -07002022 // we want a relatively stable order so that adding new fields
2023 // minimizes distruption of C++ version such as Class and Method.
2024 std::deque<Field*> grouped_and_sorted_fields;
2025 for (size_t i = 0; i < num_fields; i++) {
2026 grouped_and_sorted_fields.push_back(fields->Get(i));
2027 }
2028 std::sort(grouped_and_sorted_fields.begin(),
2029 grouped_and_sorted_fields.end(),
2030 LinkFieldsComparator());
2031
2032 // References should be at the front.
2033 size_t current_field = 0;
2034 size_t num_reference_fields = 0;
2035 for (; current_field < num_fields; current_field++) {
2036 Field* field = grouped_and_sorted_fields.front();
2037 const Class* type = field->GetTypeDuringLinking();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002038 // if a field's type at this point is NULL it isn't primitive
Brian Carlstromdbc05252011-09-09 01:59:59 -07002039 bool isPrimitive = type != NULL && type->IsPrimitive();
2040 if (isPrimitive) {
2041 break; // past last reference, move on to the next phase
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002042 }
Brian Carlstromdbc05252011-09-09 01:59:59 -07002043 grouped_and_sorted_fields.pop_front();
2044 num_reference_fields++;
2045 fields->Set(current_field, field);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002046 field->SetOffset(field_offset);
2047 field_offset = MemberOffset(field_offset.Uint32Value() + sizeof(uint32_t));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002048 }
2049
2050 // Now we want to pack all of the double-wide fields together. If
2051 // we're not aligned, though, we want to shuffle one 32-bit field
2052 // into place. If we can't find one, we'll have to pad it.
Brian Carlstromdbc05252011-09-09 01:59:59 -07002053 if (current_field != num_fields && !IsAligned(field_offset.Uint32Value(), 8)) {
2054 for (size_t i = 0; i < grouped_and_sorted_fields.size(); i++) {
2055 Field* field = grouped_and_sorted_fields[i];
2056 const Class* type = field->GetTypeDuringLinking();
2057 CHECK(type != NULL); // should only be working on primitive types
2058 DCHECK(type->IsPrimitive());
2059 if (type->IsPrimitiveLong() || type->IsPrimitiveDouble()) {
2060 continue;
2061 }
2062 fields->Set(current_field++, field);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002063 field->SetOffset(field_offset);
Brian Carlstromdbc05252011-09-09 01:59:59 -07002064 // drop the consumed field
2065 grouped_and_sorted_fields.erase(grouped_and_sorted_fields.begin() + i);
2066 break;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002067 }
Brian Carlstromdbc05252011-09-09 01:59:59 -07002068 // whether we found a 32-bit field for padding or not, we advance
2069 field_offset = MemberOffset(field_offset.Uint32Value() + sizeof(uint32_t));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002070 }
2071
2072 // Alignment is good, shuffle any double-wide fields forward, and
2073 // finish assigning field offsets to all fields.
Brian Carlstromdbc05252011-09-09 01:59:59 -07002074 DCHECK(current_field == num_fields || IsAligned(field_offset.Uint32Value(), 8));
2075 while (!grouped_and_sorted_fields.empty()) {
2076 Field* field = grouped_and_sorted_fields.front();
2077 grouped_and_sorted_fields.pop_front();
2078 const Class* type = field->GetTypeDuringLinking();
2079 CHECK(type != NULL); // should only be working on primitive types
2080 DCHECK(type->IsPrimitive());
2081 fields->Set(current_field, field);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002082 field->SetOffset(field_offset);
Brian Carlstromdbc05252011-09-09 01:59:59 -07002083 field_offset = MemberOffset(field_offset.Uint32Value() +
2084 ((type->IsPrimitiveLong() || type->IsPrimitiveDouble())
2085 ? sizeof(uint64_t)
2086 : sizeof(uint32_t)));
2087 current_field++;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002088 }
2089
2090#ifndef NDEBUG
Brian Carlstrombe977852011-07-19 14:54:54 -07002091 // Make sure that all reference fields appear before
2092 // non-reference fields, and all double-wide fields are aligned.
2093 bool seen_non_ref = false;
Brian Carlstromdbc05252011-09-09 01:59:59 -07002094 for (size_t i = 0; i < num_fields; i++) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002095 Field* field = fields->Get(i);
Brian Carlstromdbc05252011-09-09 01:59:59 -07002096 if (false) { // enable to debug field layout
Brian Carlstrom845490b2011-09-19 15:56:53 -07002097 LOG(INFO) << "LinkFields: " << (instance ? "instance" : "static")
Brian Carlstrom65ca0772011-09-24 16:03:08 -07002098 << " class=" << PrettyClass(klass)
2099 << " field=" << PrettyField(field)
Brian Carlstromdbc05252011-09-09 01:59:59 -07002100 << " offset=" << field->GetField32(MemberOffset(Field::OffsetOffset()), false);
2101 }
2102 const Class* type = field->GetTypeDuringLinking();
2103 if (type != NULL && type->IsPrimitive()) {
Brian Carlstrombe977852011-07-19 14:54:54 -07002104 if (!seen_non_ref) {
2105 seen_non_ref = true;
Brian Carlstrom4873d462011-08-21 15:23:39 -07002106 DCHECK_EQ(num_reference_fields, i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002107 }
Brian Carlstrombe977852011-07-19 14:54:54 -07002108 } else {
2109 DCHECK(!seen_non_ref);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002110 }
2111 }
Brian Carlstrombe977852011-07-19 14:54:54 -07002112 if (!seen_non_ref) {
Brian Carlstrom4873d462011-08-21 15:23:39 -07002113 DCHECK_EQ(num_fields, num_reference_fields);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002114 }
2115#endif
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002116 size = field_offset.Uint32Value();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002117 // Update klass
Brian Carlstromdbc05252011-09-09 01:59:59 -07002118 if (instance) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002119 klass->SetNumReferenceInstanceFields(num_reference_fields);
Brian Carlstromdbc05252011-09-09 01:59:59 -07002120 if (!klass->IsVariableSize()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002121 klass->SetObjectSize(size);
2122 }
2123 } else {
2124 klass->SetNumReferenceStaticFields(num_reference_fields);
2125 klass->SetClassSize(size);
2126 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002127 return true;
2128}
2129
2130// Set the bitmap of reference offsets, refOffsets, from the ifields
2131// list.
Brian Carlstrom4873d462011-08-21 15:23:39 -07002132void ClassLinker::CreateReferenceInstanceOffsets(Class* klass) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002133 uint32_t reference_offsets = 0;
2134 Class* super_class = klass->GetSuperClass();
2135 if (super_class != NULL) {
2136 reference_offsets = super_class->GetReferenceInstanceOffsets();
Brian Carlstrom4873d462011-08-21 15:23:39 -07002137 // If our superclass overflowed, we don't stand a chance.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002138 if (reference_offsets == CLASS_WALK_SUPER) {
2139 klass->SetReferenceInstanceOffsets(reference_offsets);
Brian Carlstrom4873d462011-08-21 15:23:39 -07002140 return;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002141 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002142 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002143 CreateReferenceOffsets(klass, true, reference_offsets);
Brian Carlstrom4873d462011-08-21 15:23:39 -07002144}
2145
2146void ClassLinker::CreateReferenceStaticOffsets(Class* klass) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002147 CreateReferenceOffsets(klass, false, 0);
Brian Carlstrom4873d462011-08-21 15:23:39 -07002148}
2149
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002150void ClassLinker::CreateReferenceOffsets(Class* klass, bool instance,
2151 uint32_t reference_offsets) {
2152 size_t num_reference_fields =
2153 instance ? klass->NumReferenceInstanceFieldsDuringLinking()
2154 : klass->NumReferenceStaticFieldsDuringLinking();
2155 const ObjectArray<Field>* fields =
2156 instance ? klass->GetIFields() : klass->GetSFields();
Brian Carlstrom4873d462011-08-21 15:23:39 -07002157 // All of the fields that contain object references are guaranteed
2158 // to be at the beginning of the fields list.
2159 for (size_t i = 0; i < num_reference_fields; ++i) {
2160 // Note that byte_offset is the offset from the beginning of
2161 // object, not the offset into instance data
2162 const Field* field = fields->Get(i);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002163 MemberOffset byte_offset = field->GetOffsetDuringLinking();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002164 CHECK_EQ(byte_offset.Uint32Value() & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
2165 if (CLASS_CAN_ENCODE_OFFSET(byte_offset.Uint32Value())) {
2166 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset.Uint32Value());
Brian Carlstrom4873d462011-08-21 15:23:39 -07002167 CHECK_NE(new_bit, 0U);
2168 reference_offsets |= new_bit;
2169 } else {
2170 reference_offsets = CLASS_WALK_SUPER;
2171 break;
2172 }
2173 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002174 // Update fields in klass
2175 if (instance) {
2176 klass->SetReferenceInstanceOffsets(reference_offsets);
2177 } else {
2178 klass->SetReferenceStaticOffsets(reference_offsets);
2179 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002180}
2181
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002182String* ClassLinker::ResolveString(const DexFile& dex_file,
Elliott Hughescf4c6c42011-09-01 15:16:42 -07002183 uint32_t string_idx, DexCache* dex_cache) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002184 String* resolved = dex_cache->GetResolvedString(string_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002185 if (resolved != NULL) {
2186 return resolved;
2187 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002188 const DexFile::StringId& string_id = dex_file.GetStringId(string_idx);
2189 int32_t utf16_length = dex_file.GetStringLength(string_id);
2190 const char* utf8_data = dex_file.GetStringData(string_id);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002191 // TODO: remote the const_cast below
2192 String* string = const_cast<String*>(intern_table_->InternStrong(utf16_length, utf8_data));
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002193 dex_cache->SetResolvedString(string_idx, string);
2194 return string;
2195}
2196
2197Class* ClassLinker::ResolveType(const DexFile& dex_file,
2198 uint32_t type_idx,
2199 DexCache* dex_cache,
2200 const ClassLoader* class_loader) {
2201 Class* resolved = dex_cache->GetResolvedType(type_idx);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002202 if (resolved == NULL) {
2203 const char* descriptor = dex_file.dexStringByTypeIdx(type_idx);
2204 if (descriptor[1] == '\0') {
2205 // only the descriptors of primitive types should be 1 character long
2206 resolved = FindPrimitiveClass(descriptor[0]);
2207 } else {
2208 resolved = FindClass(descriptor, class_loader);
2209 }
2210 if (resolved != NULL) {
2211 Class* check = resolved->IsArrayClass() ? resolved->GetComponentType() : resolved;
2212 if (dex_cache != check->GetDexCache()) {
2213 if (check->GetClassLoader() != NULL) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07002214 Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;",
2215 "Class with type index %d resolved by unexpected .dex", type_idx);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002216 resolved = NULL;
2217 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002218 }
2219 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002220 if (resolved != NULL) {
2221 dex_cache->SetResolvedType(type_idx, resolved);
2222 } else {
2223 DCHECK(Thread::Current()->IsExceptionPending());
2224 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002225 }
2226 return resolved;
2227}
2228
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002229Method* ClassLinker::ResolveMethod(const DexFile& dex_file,
2230 uint32_t method_idx,
2231 DexCache* dex_cache,
2232 const ClassLoader* class_loader,
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002233 bool is_direct) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002234 Method* resolved = dex_cache->GetResolvedMethod(method_idx);
2235 if (resolved != NULL) {
2236 return resolved;
2237 }
2238 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
2239 Class* klass = ResolveType(dex_file, method_id.class_idx_, dex_cache, class_loader);
2240 if (klass == NULL) {
2241 return NULL;
2242 }
2243
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002244 const char* name = dex_file.dexStringById(method_id.name_idx_);
Elliott Hughes0c424cb2011-08-26 10:16:25 -07002245 std::string signature(dex_file.CreateMethodDescriptor(method_id.proto_idx_, NULL));
Brian Carlstrom7540ff42011-09-04 16:38:46 -07002246 if (is_direct) {
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002247 resolved = klass->FindDirectMethod(name, signature);
Brian Carlstrom7540ff42011-09-04 16:38:46 -07002248 } else if (klass->IsInterface()) {
2249 resolved = klass->FindInterfaceMethod(name, signature);
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002250 } else {
2251 resolved = klass->FindVirtualMethod(name, signature);
2252 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002253 if (resolved != NULL) {
2254 dex_cache->SetResolvedMethod(method_idx, resolved);
2255 } else {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07002256 DCHECK(Thread::Current()->IsExceptionPending());
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002257 }
2258 return resolved;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002259}
2260
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002261Field* ClassLinker::ResolveField(const DexFile& dex_file,
2262 uint32_t field_idx,
2263 DexCache* dex_cache,
2264 const ClassLoader* class_loader,
2265 bool is_static) {
2266 Field* resolved = dex_cache->GetResolvedField(field_idx);
2267 if (resolved != NULL) {
2268 return resolved;
2269 }
2270 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
2271 Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
2272 if (klass == NULL) {
2273 return NULL;
2274 }
2275
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002276 const char* name = dex_file.dexStringById(field_id.name_idx_);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002277 Class* field_type = ResolveType(dex_file, field_id.type_idx_, dex_cache, class_loader);
Brian Carlstrom65ca0772011-09-24 16:03:08 -07002278 if (field_type == NULL) {
2279 // TODO: LinkageError?
2280 UNIMPLEMENTED(WARNING) << "Failed to resolve type of field " << name
2281 << " in " << PrettyClass(klass);
2282 return NULL;
2283}
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002284 if (is_static) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002285 resolved = klass->FindStaticField(name, field_type);
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002286 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07002287 resolved = klass->FindInstanceField(name, field_type);
Brian Carlstrom20cfffa2011-08-26 02:31:27 -07002288 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002289 if (resolved != NULL) {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07002290 dex_cache->SetResolvedField(field_idx, resolved);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002291 } else {
Elliott Hughes4a2b4172011-09-20 17:08:25 -07002292 DCHECK(Thread::Current()->IsExceptionPending());
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07002293 }
2294 return resolved;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07002295}
2296
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07002297void ClassLinker::DumpAllClasses(int flags) const {
2298 // TODO: at the time this was written, it wasn't safe to call PrettyField with the ClassLinker
2299 // lock held, because it might need to resolve a field's type, which would try to take the lock.
2300 std::vector<Class*> all_classes;
2301 {
2302 MutexLock mu(lock_);
2303 typedef Table::const_iterator It; // TODO: C++0x auto
2304 for (It it = classes_.begin(), end = classes_.end(); it != end; ++it) {
2305 all_classes.push_back(it->second);
2306 }
2307 }
2308
2309 for (size_t i = 0; i < all_classes.size(); ++i) {
2310 all_classes[i]->DumpClass(std::cerr, flags);
2311 }
2312}
2313
Elliott Hughese27955c2011-08-26 15:21:24 -07002314size_t ClassLinker::NumLoadedClasses() const {
Brian Carlstrom16192862011-09-12 17:50:06 -07002315 MutexLock mu(lock_);
Elliott Hughese27955c2011-08-26 15:21:24 -07002316 return classes_.size();
2317}
2318
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07002319} // namespace art