blob: ff5bc81f8aeeca69df4ac3877921c2a5210a9f17 [file] [log] [blame]
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: cshapiro@google.com (Carl Shapiro)
3
4#include "src/class_linker.h"
5
6#include <vector>
7#include <utility>
8
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07009#include "src/casts.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070010#include "src/dex_verifier.h"
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070011#include "src/heap.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070012#include "src/logging.h"
13#include "src/monitor.h"
14#include "src/object.h"
15#include "src/raw_dex_file.h"
16#include "src/scoped_ptr.h"
17#include "src/thread.h"
18#include "src/utils.h"
19
20namespace art {
21
Carl Shapiro61e019d2011-07-14 16:53:09 -070022ClassLinker* ClassLinker::Create() {
23 scoped_ptr<ClassLinker> class_linker(new ClassLinker);
24 class_linker->Init();
25 // TODO: check for failure during initialization
26 return class_linker.release();
27}
28
Carl Shapiro565f5072011-07-10 13:39:43 -070029void ClassLinker::Init() {
Brian Carlstroma0808032011-07-18 00:39:23 -070030 // Allocate and partially initialize the Class, Object, Field, Method classes.
Brian Carlstrom934486c2011-07-12 23:42:50 -070031 // Initialization will be completed when the definitions are loaded.
Brian Carlstroma0808032011-07-18 00:39:23 -070032 java_lang_Class_ = reinterpret_cast<Class*>(Heap::AllocRaw(sizeof(Class), NULL));
Brian Carlstroma331b3c2011-07-18 17:47:56 -070033 CHECK(java_lang_Class_ != NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070034 java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
Brian Carlstroma0808032011-07-18 00:39:23 -070035 java_lang_Class_->object_size_ = sizeof(Class);
36 java_lang_Class_->klass_ = java_lang_Class_;
37
38 java_lang_Object_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070039 CHECK(java_lang_Object_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070040 java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
41
42 java_lang_Class_->super_class_ = java_lang_Object_;
43
44 java_lang_ref_Field_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070045 CHECK(java_lang_ref_Field_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070046 java_lang_ref_Field_->descriptor_ = "Ljava/lang/ref/Field;";
47
48 java_lang_ref_Method_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070049 CHECK(java_lang_ref_Method_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070050 java_lang_ref_Method_->descriptor_ = "Ljava/lang/Method;";
Carl Shapiro565f5072011-07-10 13:39:43 -070051
Brian Carlstroma331b3c2011-07-18 17:47:56 -070052 java_lang_Cloneable_ = AllocClass(NULL);
53 CHECK(java_lang_Cloneable_ != NULL);
54 java_lang_Cloneable_->descriptor_ = "Ljava/lang/Cloneable;";
Brian Carlstroma0808032011-07-18 00:39:23 -070055
Brian Carlstroma331b3c2011-07-18 17:47:56 -070056 java_io_Serializable_ = AllocClass(NULL);
57 CHECK(java_io_Serializable_ != NULL);
58 java_io_Serializable_->descriptor_ = "Ljava/io/Serializable;";
59
60 java_lang_String_ = AllocClass(NULL);
61 CHECK(java_lang_String_ != NULL);
62 java_lang_String_->descriptor_ = "Ljava/lang/String;";
63
64 // Allocate and initialize the primitive type classes.
65 primitive_byte_ = CreatePrimitiveClass("B");
66 primitive_char_ = CreatePrimitiveClass("C");
67 primitive_double_ = CreatePrimitiveClass("D");
68 primitive_float_ = CreatePrimitiveClass("F");
69 primitive_int_ = CreatePrimitiveClass("I");
70 primitive_long_ = CreatePrimitiveClass("J");
71 primitive_short_ = CreatePrimitiveClass("S");
72 primitive_boolean_ = CreatePrimitiveClass("Z");
73 primitive_void_ = CreatePrimitiveClass("V");
74
75 char_array_class_ = FindSystemClass("[C");
76 CHECK(char_array_class_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070077}
78
79Class* ClassLinker::AllocClass(DexFile* dex_file) {
80 Class* klass = reinterpret_cast<Class*>(Heap::AllocObject(java_lang_Class_));
81 klass->dex_file_ = dex_file;
82 return klass;
83}
84
85StaticField* ClassLinker::AllocStaticField() {
86 return reinterpret_cast<StaticField*>(Heap::AllocRaw(sizeof(StaticField), java_lang_ref_Field_));
87}
88
89InstanceField* ClassLinker::AllocInstanceField() {
90 return reinterpret_cast<InstanceField*>(Heap::AllocRaw(sizeof(InstanceField), java_lang_ref_Field_));
91}
92
93Method* ClassLinker::AllocMethod() {
94 return reinterpret_cast<Method*>(Heap::AllocRaw(sizeof(Method), java_lang_ref_Method_));
Carl Shapiro565f5072011-07-10 13:39:43 -070095}
96
Brian Carlstrom6cc18452011-07-18 15:10:33 -070097Class* ClassLinker::FindClass(const StringPiece& descriptor,
98 Object* class_loader) {
Carl Shapirob5573532011-07-12 18:22:59 -070099 Thread* self = Thread::Current();
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700100 DCHECK(self != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700101 CHECK(!self->IsExceptionPending());
102 // Find the class in the loaded classes table.
103 Class* klass = LookupClass(descriptor, class_loader);
104 if (klass == NULL) {
105 // Class is not yet loaded.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700106 if (descriptor[0] == '[') {
107 return CreateArrayClass(descriptor, class_loader);
108 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700109 ClassPathEntry pair = FindInClassPath(descriptor);
110 if (pair.first == NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700111 LG << "Class " << descriptor << " not found"; // TODO: NoClassDefFoundError
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700112 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700113 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700114 DexFile* dex_file = pair.first;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700115 const RawDexFile::ClassDef* class_def = pair.second;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700116 // Load the class from the dex file.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700117 if (descriptor == "Ljava/lang/Object;") {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700118 klass = java_lang_Object_;
119 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700120 klass->object_size_ = sizeof(Object);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700121 char_array_class_->super_class_idx_ = class_def->class_idx_;
122 } else if (descriptor == "Ljava/lang/Class;") {
Carl Shapiro565f5072011-07-10 13:39:43 -0700123 klass = java_lang_Class_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700124 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700125 klass->object_size_ = sizeof(Class);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700126 } else if (descriptor == "Ljava/lang/ref/Field;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700127 klass = java_lang_ref_Field_;
128 klass->dex_file_ = dex_file;
129 klass->object_size_ = sizeof(Field);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700130 } else if (descriptor == "Ljava/lang/ref/Method;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700131 klass = java_lang_ref_Method_;
132 klass->dex_file_ = dex_file;
133 klass->object_size_ = sizeof(Method);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700134 } else if (descriptor == "Ljava/lang/Cloneable;") {
135 klass = java_lang_Cloneable_;
136 klass->dex_file_ = dex_file;
137 } else if (descriptor == "Ljava/io/Serializable;") {
138 klass = java_io_Serializable_;
139 klass->dex_file_ = dex_file;
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700140 } else if (descriptor == "Ljava/lang/String;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700141 klass = java_lang_String_;
142 klass->dex_file_ = dex_file;
143 klass->object_size_ = sizeof(String);
Carl Shapiro565f5072011-07-10 13:39:43 -0700144 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -0700145 klass = AllocClass(dex_file);
Carl Shapiro565f5072011-07-10 13:39:43 -0700146 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700147 LoadClass(*class_def, klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700148 // Check for a pending exception during load
149 if (self->IsExceptionPending()) {
150 // TODO: free native allocations in klass
151 return NULL;
152 }
153 {
154 ObjectLock lock(klass);
Carl Shapirob5573532011-07-12 18:22:59 -0700155 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700156 // Add the newly loaded class to the loaded classes table.
157 bool success = InsertClass(klass);
158 if (!success) {
159 // We may fail to insert if we raced with another thread.
160 klass->clinit_thread_id_ = 0;
161 // TODO: free native allocations in klass
162 klass = LookupClass(descriptor, class_loader);
163 CHECK(klass != NULL);
164 } else {
165 // Link the class.
166 if (!LinkClass(klass)) {
167 // Linking failed.
168 // TODO: CHECK(self->IsExceptionPending());
169 lock.NotifyAll();
170 return NULL;
171 }
172 }
173 }
174 }
175 // Link the class if it has not already been linked.
176 if (!klass->IsLinked() && !klass->IsErroneous()) {
177 ObjectLock lock(klass);
178 // Check for circular dependencies between classes.
Carl Shapirob5573532011-07-12 18:22:59 -0700179 if (!klass->IsLinked() && klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700180 LG << "Recursive link"; // TODO: ClassCircularityError
181 return NULL;
182 }
183 // Wait for the pending initialization to complete.
184 while (!klass->IsLinked() && !klass->IsErroneous()) {
185 lock.Wait();
186 }
187 }
188 if (klass->IsErroneous()) {
189 LG << "EarlierClassFailure"; // TODO: EarlierClassFailure
190 return NULL;
191 }
192 // Return the loaded class. No exceptions should be pending.
193 CHECK(!self->IsExceptionPending());
194 return klass;
195}
196
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700197void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700198 CHECK(klass != NULL);
199 CHECK(klass->dex_file_ != NULL);
200 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
201 const byte* class_data = raw->GetClassData(class_def);
202 RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
203
204 const char* descriptor = raw->GetClassDescriptor(class_def);
205 CHECK(descriptor != NULL);
206
207 klass->klass_ = java_lang_Class_;
208 klass->descriptor_.set(descriptor);
209 klass->descriptor_alloc_ = NULL;
210 klass->access_flags_ = class_def.access_flags_;
211 klass->class_loader_ = NULL; // TODO
212 klass->primitive_type_ = Class::kPrimNot;
213 klass->status_ = Class::kStatusIdx;
214
215 klass->super_class_ = NULL;
216 klass->super_class_idx_ = class_def.superclass_idx_;
217
218 klass->num_sfields_ = header.static_fields_size_;
219 klass->num_ifields_ = header.instance_fields_size_;
220 klass->num_direct_methods_ = header.direct_methods_size_;
221 klass->num_virtual_methods_ = header.virtual_methods_size_;
222
223 klass->source_file_ = raw->dexGetSourceFile(class_def);
224
225 // Load class interfaces.
226 LoadInterfaces(class_def, klass);
227
228 // Load static fields.
229 if (klass->num_sfields_ != 0) {
230 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700231 klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700232 uint32_t last_idx = 0;
233 for (size_t i = 0; i < klass->num_sfields_; ++i) {
234 RawDexFile::Field raw_field;
235 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700236 StaticField* sfield = AllocStaticField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700237 klass->sfields_[i] = sfield;
238 LoadField(klass, raw_field, sfield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700239 }
240 }
241
242 // Load instance fields.
243 if (klass->NumInstanceFields() != 0) {
244 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700245 klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700246 uint32_t last_idx = 0;
247 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
248 RawDexFile::Field raw_field;
249 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700250 InstanceField* ifield = AllocInstanceField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700251 klass->ifields_[i] = ifield;
252 LoadField(klass, raw_field, ifield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700253 }
254 }
255
256 // Load direct methods.
257 if (klass->NumDirectMethods() != 0) {
258 // TODO: append direct methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700259 klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700260 uint32_t last_idx = 0;
261 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
262 RawDexFile::Method raw_method;
263 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700264 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700265 klass->direct_methods_[i] = meth;
266 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700267 // TODO: register maps
268 }
269 }
270
271 // Load virtual methods.
272 if (klass->NumVirtualMethods() != 0) {
273 // TODO: append virtual methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700274 klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700275 uint32_t last_idx = 0;
276 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
277 RawDexFile::Method raw_method;
278 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700279 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700280 klass->virtual_methods_[i] = meth;
281 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700282 // TODO: register maps
283 }
284 }
Brian Carlstrom934486c2011-07-12 23:42:50 -0700285}
286
287void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
288 Class* klass) {
289 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
290 const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
291 if (list != NULL) {
292 klass->interface_count_ = list->Size();
293 // TODO: allocate the interfaces array on the object heap.
294 klass->interfaces_ = new Class*[list->Size()]();
295 for (size_t i = 0; i < list->Size(); ++i) {
296 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
297 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
298 }
299 }
300}
301
302void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
303 Field* dst) {
304 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
305 const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
306 dst->klass_ = klass;
307 dst->name_ = raw->dexStringById(field_id.name_idx_);
308 dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
309 dst->access_flags_ = src.access_flags_;
310}
311
312void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
313 Method* dst) {
314 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
315 const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
316 dst->klass_ = klass;
317 dst->name_.set(raw->dexStringById(method_id.name_idx_));
318 dst->proto_idx_ = method_id.proto_idx_;
319 dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
320 dst->access_flags_ = src.access_flags_;
321
322 // TODO: check for finalize method
323
324 const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
325 if (code_item != NULL) {
326 dst->num_registers_ = code_item->registers_size_;
327 dst->num_ins_ = code_item->ins_size_;
328 dst->num_outs_ = code_item->outs_size_;
329 dst->insns_ = code_item->insns_;
330 } else {
331 uint16_t num_args = dst->NumArgRegisters();
332 if (!dst->IsStatic()) {
333 ++num_args;
334 }
335 dst->num_registers_ = dst->num_ins_ + num_args;
336 // TODO: native methods
337 }
338}
339
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700340ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const StringPiece& descriptor) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700341 for (size_t i = 0; i != class_path_.size(); ++i) {
342 DexFile* dex_file = class_path_[i];
Brian Carlstroma0808032011-07-18 00:39:23 -0700343 const RawDexFile::ClassDef* class_def = dex_file->GetRaw()->FindClassDef(descriptor);
344 if (class_def != NULL) {
345 return ClassPathEntry(dex_file, class_def);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700346 }
347 }
Brian Carlstroma0808032011-07-18 00:39:23 -0700348 return ClassPathEntry(NULL, NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700349}
350
351void ClassLinker::AppendToClassPath(DexFile* dex_file) {
352 class_path_.push_back(dex_file);
353}
354
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700355Class* ClassLinker::CreatePrimitiveClass(const StringPiece& descriptor) {
Brian Carlstroma0808032011-07-18 00:39:23 -0700356 Class* klass = AllocClass(NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -0700357 CHECK(klass != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -0700358 klass->super_class_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700359 klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
360 klass->descriptor_ = descriptor;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700361 klass->descriptor_alloc_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700362 klass->status_ = Class::kStatusInitialized;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700363 bool success = InsertClass(klass);
364 CHECK(success);
Carl Shapiro565f5072011-07-10 13:39:43 -0700365 return klass;
366}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700367
Brian Carlstrombe977852011-07-19 14:54:54 -0700368// Create an array class (i.e. the class object for the array, not the
369// array itself). "descriptor" looks like "[C" or "[[[[B" or
370// "[Ljava/lang/String;".
371//
372// If "descriptor" refers to an array of primitives, look up the
373// primitive type's internally-generated class object.
374//
375// "loader" is the class loader of the class that's referring to us. It's
376// used to ensure that we're looking for the element type in the right
377// context. It does NOT become the class loader for the array class; that
378// always comes from the base element class.
379//
380// Returns NULL with an exception raised on failure.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700381Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* class_loader)
382{
383 CHECK(descriptor[0] == '[');
384 DCHECK(java_lang_Class_ != NULL);
385 DCHECK(java_lang_Object_ != NULL);
386
Brian Carlstrombe977852011-07-19 14:54:54 -0700387 // Identify the underlying element class and the array dimension depth.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700388 Class* component_type_ = NULL;
389 int array_rank;
390 if (descriptor[1] == '[') {
Brian Carlstrombe977852011-07-19 14:54:54 -0700391 // array of arrays; keep descriptor and grab stuff from parent
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700392 Class* outer = FindClass(descriptor.substr(1), class_loader);
393 if (outer != NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700394 // want the base class, not "outer", in our component_type_
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700395 component_type_ = outer->component_type_;
396 array_rank = outer->array_rank_ + 1;
397 } else {
Brian Carlstrombe977852011-07-19 14:54:54 -0700398 DCHECK(component_type_ == NULL); // make sure we fail
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700399 }
400 } else {
401 array_rank = 1;
402 if (descriptor[1] == 'L') {
Brian Carlstrombe977852011-07-19 14:54:54 -0700403 // array of objects; strip off "[" and look up descriptor.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700404 const StringPiece subDescriptor = descriptor.substr(1);
405 LG << "searching for element class '" << subDescriptor << "'";
Brian Carlstrombe977852011-07-19 14:54:54 -0700406 component_type_ = FindClass(subDescriptor, class_loader); // TODO FindClassNoInit
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700407 } else {
Brian Carlstrombe977852011-07-19 14:54:54 -0700408 // array of a primitive type
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700409 component_type_ = FindPrimitiveClass(descriptor[1]);
410 }
411 }
412
413 if (component_type_ == NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700414 // failed
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700415 DCHECK(Thread::Current()->IsExceptionPending());
416 return NULL;
417 }
418
Brian Carlstrombe977852011-07-19 14:54:54 -0700419 // See if the component type is already loaded. Array classes are
420 // always associated with the class loader of their underlying
421 // element type -- an array of Strings goes with the loader for
422 // java/lang/String -- so we need to look for it there. (The
423 // caller should have checked for the existence of the class
424 // before calling here, but they did so with *their* class loader,
425 // not the component type's loader.)
426 //
427 // If we find it, the caller adds "loader" to the class' initiating
428 // loader list, which should prevent us from going through this again.
429 //
430 // This call is unnecessary if "loader" and "component_type_->class_loader_"
431 // are the same, because our caller (FindClass) just did the
432 // lookup. (Even if we get this wrong we still have correct behavior,
433 // because we effectively do this lookup again when we add the new
434 // class to the hash table --- necessary because of possible races with
435 // other threads.)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700436 if (class_loader != component_type_->class_loader_) {
437 Class* new_class = LookupClass(descriptor, component_type_->class_loader_);
438 if (new_class != NULL) {
439 return new_class;
440 }
441 }
442
Brian Carlstrombe977852011-07-19 14:54:54 -0700443 // Fill out the fields in the Class.
444 //
445 // It is possible to execute some methods against arrays, because
446 // all arrays are subclasses of java_lang_Object_, so we need to set
447 // up a vtable. We can just point at the one in java_lang_Object_.
448 //
449 // Array classes are simple enough that we don't need to do a full
450 // link step.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700451 Class* new_class = AllocClass(NULL);
452 if (new_class == NULL) {
453 return NULL;
454 }
455 new_class->descriptor_alloc_ = new std::string(descriptor.data(),
456 descriptor.size());
457 new_class->descriptor_.set(new_class->descriptor_alloc_->data(),
458 new_class->descriptor_alloc_->size());
459 new_class->super_class_ = java_lang_Object_;
460 new_class->vtable_count_ = java_lang_Object_->vtable_count_;
461 new_class->vtable_ = java_lang_Object_->vtable_;
462 new_class->primitive_type_ = Class::kPrimNot;
463 new_class->component_type_ = component_type_;
464 new_class->class_loader_ = component_type_->class_loader_;
465 new_class->array_rank_ = array_rank;
466 new_class->status_ = Class::kStatusInitialized;
Brian Carlstrombe977852011-07-19 14:54:54 -0700467 // don't need to set new_class->object_size_
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700468
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700469
Brian Carlstrombe977852011-07-19 14:54:54 -0700470 // All arrays have java/lang/Cloneable and java/io/Serializable as
471 // interfaces. We need to set that up here, so that stuff like
472 // "instanceof" works right.
473 //
474 // Note: The GC could run during the call to FindSystemClassNoInit(),
475 // so we need to make sure the class object is GC-valid while we're in
476 // there. Do this by clearing the interface list so the GC will just
477 // think that the entries are null.
478 //
479 // TODO?
480 // We may want to create a single, global copy of "interfaces" and
481 // "iftable" somewhere near the start and just point to those (and
482 // remember not to free them for arrays).
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700483 new_class->interface_count_ = 2;
484 new_class->interfaces_ = new Class*[2];
485 memset(new_class->interfaces_, 0, sizeof(Class*) * 2);
486 new_class->interfaces_[0] = java_lang_Cloneable_;
487 new_class->interfaces_[1] = java_io_Serializable_;
Brian Carlstrombe977852011-07-19 14:54:54 -0700488
489 // We assume that Cloneable/Serializable don't have superinterfaces --
490 // normally we'd have to crawl up and explicitly list all of the
491 // supers as well. These interfaces don't have any methods, so we
492 // don't have to worry about the ifviPool either.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700493 new_class->iftable_count_ = 2;
494 new_class->iftable_ = new InterfaceEntry[2];
495 memset(new_class->iftable_, 0, sizeof(InterfaceEntry) * 2);
496 new_class->iftable_[0].SetClass(new_class->interfaces_[0]);
497 new_class->iftable_[1].SetClass(new_class->interfaces_[1]);
498
Brian Carlstrombe977852011-07-19 14:54:54 -0700499 // Inherit access flags from the component type. Arrays can't be
500 // used as a superclass or interface, so we want to add "final"
501 // and remove "interface".
502 //
503 // Don't inherit any non-standard flags (e.g., kAccFinal)
504 // from component_type_. We assume that the array class does not
505 // override finalize().
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700506 new_class->access_flags_ = ((new_class->component_type_->access_flags_ &
507 ~kAccInterface) | kAccFinal) & kAccJavaFlagsMask;
508
509 if (InsertClass(new_class)) {
510 return new_class;
511 }
Brian Carlstrombe977852011-07-19 14:54:54 -0700512 // Another thread must have loaded the class after we
513 // started but before we finished. Abandon what we've
514 // done.
515 //
516 // (Yes, this happens.)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700517
Brian Carlstrombe977852011-07-19 14:54:54 -0700518 // Grab the winning class.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700519 Class* other_class = LookupClass(descriptor, component_type_->class_loader_);
520 DCHECK(other_class != NULL);
521 return other_class;
522}
523
524Class* ClassLinker::FindPrimitiveClass(char type) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700525 switch (type) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700526 case 'B':
Carl Shapiro565f5072011-07-10 13:39:43 -0700527 CHECK(primitive_byte_ != NULL);
528 return primitive_byte_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700529 case 'C':
Carl Shapiro565f5072011-07-10 13:39:43 -0700530 CHECK(primitive_char_ != NULL);
531 return primitive_char_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700532 case 'D':
Carl Shapiro565f5072011-07-10 13:39:43 -0700533 CHECK(primitive_double_ != NULL);
534 return primitive_double_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700535 case 'F':
Carl Shapiro565f5072011-07-10 13:39:43 -0700536 CHECK(primitive_float_ != NULL);
537 return primitive_float_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700538 case 'I':
Carl Shapiro565f5072011-07-10 13:39:43 -0700539 CHECK(primitive_int_ != NULL);
540 return primitive_int_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700541 case 'J':
Carl Shapiro565f5072011-07-10 13:39:43 -0700542 CHECK(primitive_long_ != NULL);
543 return primitive_long_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700544 case 'S':
Carl Shapiro565f5072011-07-10 13:39:43 -0700545 CHECK(primitive_short_ != NULL);
546 return primitive_short_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700547 case 'Z':
Carl Shapiro565f5072011-07-10 13:39:43 -0700548 CHECK(primitive_boolean_ != NULL);
549 return primitive_boolean_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700550 case 'V':
Carl Shapiro565f5072011-07-10 13:39:43 -0700551 CHECK(primitive_void_ != NULL);
552 return primitive_void_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700553 case 'L':
554 case '[':
555 LOG(ERROR) << "Not a primitive type " << static_cast<int>(type);
Carl Shapiro565f5072011-07-10 13:39:43 -0700556 default:
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700557 LOG(ERROR) << "Unknown primitive type " << static_cast<int>(type);
Carl Shapiro565f5072011-07-10 13:39:43 -0700558 };
559 return NULL; // Not reachable.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700560}
561
562bool ClassLinker::InsertClass(Class* klass) {
563 // TODO: acquire classes_lock_
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700564 const StringPiece& key = klass->GetDescriptor();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700565 bool success = classes_.insert(std::make_pair(key, klass)).second;
566 // TODO: release classes_lock_
567 return success;
568}
569
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700570Class* ClassLinker::LookupClass(const StringPiece& descriptor, Object* class_loader) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700571 // TODO: acquire classes_lock_
572 Table::iterator it = classes_.find(descriptor);
573 // TODO: release classes_lock_
574 if (it == classes_.end()) {
575 return NULL;
576 } else {
577 return (*it).second;
578 }
579}
580
581bool ClassLinker::InitializeClass(Class* klass) {
582 CHECK(klass->GetStatus() == Class::kStatusResolved ||
583 klass->GetStatus() == Class::kStatusError);
584
Carl Shapirob5573532011-07-12 18:22:59 -0700585 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700586
587 {
588 ObjectLock lock(klass);
589
590 if (klass->GetStatus() < Class::kStatusVerified) {
591 if (klass->IsErroneous()) {
592 LG << "re-initializing failed class"; // TODO: throw
593 return false;
594 }
595
596 CHECK(klass->GetStatus() == Class::kStatusResolved);
597
598 klass->status_ = Class::kStatusVerifying;
599 if (!DexVerify::VerifyClass(klass)) {
600 LG << "Verification failed"; // TODO: ThrowVerifyError
601 Object* exception = self->GetException();
602 klass->SetObjectAt(OFFSETOF_MEMBER(Class, verify_error_class_),
603 exception->GetClass());
604 klass->SetStatus(Class::kStatusError);
605 return false;
606 }
607
608 klass->SetStatus(Class::kStatusVerified);
609 }
610
611 if (klass->status_ == Class::kStatusInitialized) {
612 return true;
613 }
614
615 while (klass->status_ == Class::kStatusInitializing) {
616 // we caught somebody else in the act; was it us?
Carl Shapirob5573532011-07-12 18:22:59 -0700617 if (klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700618 LG << "recursive <clinit>";
619 return true;
620 }
621
622 CHECK(!self->IsExceptionPending());
623
624 lock.Wait(); // TODO: check for interruption
625
626 // When we wake up, repeat the test for init-in-progress. If
627 // there's an exception pending (only possible if
628 // "interruptShouldThrow" was set), bail out.
629 if (self->IsExceptionPending()) {
630 CHECK(false);
631 LG << "Exception in initialization."; // TODO: ExceptionInInitializerError
632 klass->SetStatus(Class::kStatusError);
633 return false;
634 }
635 if (klass->GetStatus() == Class::kStatusInitializing) {
636 continue;
637 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700638 DCHECK(klass->GetStatus() == Class::kStatusInitialized ||
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700639 klass->GetStatus() == Class::kStatusError);
640 if (klass->IsErroneous()) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700641 // The caller wants an exception, but it was thrown in a
642 // different thread. Synthesize one here.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700643 LG << "<clinit> failed"; // TODO: throw UnsatisfiedLinkError
644 return false;
645 }
646 return true; // otherwise, initialized
647 }
648
649 // see if we failed previously
650 if (klass->IsErroneous()) {
651 // might be wise to unlock before throwing; depends on which class
652 // it is that we have locked
653
654 // TODO: throwEarlierClassFailure(klass);
655 return false;
656 }
657
658 if (!ValidateSuperClassDescriptors(klass)) {
659 klass->SetStatus(Class::kStatusError);
660 return false;
661 }
662
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700663 DCHECK(klass->status_ < Class::kStatusInitializing);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700664
Carl Shapirob5573532011-07-12 18:22:59 -0700665 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700666 klass->status_ = Class::kStatusInitializing;
667 }
668
669 if (!InitializeSuperClass(klass)) {
670 return false;
671 }
672
673 InitializeStaticFields(klass);
674
675 Method* clinit = klass->FindDirectMethodLocally("<clinit>", "()V");
676 if (clinit != NULL) {
677 } else {
678 // JValue unused;
679 // TODO: dvmCallMethod(self, method, NULL, &unused);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700680 //CHECK(!"unimplemented");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700681 }
682
683 {
684 ObjectLock lock(klass);
685
686 if (self->IsExceptionPending()) {
687 klass->SetStatus(Class::kStatusError);
688 } else {
689 klass->SetStatus(Class::kStatusInitialized);
690 }
691 lock.NotifyAll();
692 }
693
694 return true;
695}
696
697bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
698 if (klass->IsInterface()) {
699 return true;
700 }
701 // begin with the methods local to the superclass
702 if (klass->HasSuperClass() &&
703 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
704 const Class* super = klass->GetSuperClass();
705 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
706 const Method* method = klass->GetVirtualMethod(i);
707 if (method != super->GetVirtualMethod(i) &&
708 !HasSameMethodDescriptorClasses(method, super, klass)) {
709 LG << "Classes resolve differently in superclass";
710 return false;
711 }
712 }
713 }
714 for (size_t i = 0; i < klass->iftable_count_; ++i) {
715 const InterfaceEntry* iftable = &klass->iftable_[i];
716 Class* interface = iftable->GetClass();
717 if (klass->GetClassLoader() != interface->GetClassLoader()) {
718 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
719 uint32_t vtable_index = iftable->method_index_array_[j];
720 const Method* method = klass->GetVirtualMethod(vtable_index);
721 if (!HasSameMethodDescriptorClasses(method, interface,
722 method->GetClass())) {
723 LG << "Classes resolve differently in interface"; // TODO: LinkageError
724 return false;
725 }
726 }
727 }
728 }
729 return true;
730}
731
732bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700733 const Class* klass1,
734 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700735 const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
736 const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
737 RawDexFile::ParameterIterator *it;
738 for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
739 const char* descriptor = it->GetDescriptor();
740 if (descriptor == NULL) {
741 break;
742 }
743 if (descriptor[0] == 'L' || descriptor[0] == '[') {
744 // Found a non-primitive type.
745 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
746 return false;
747 }
748 }
749 }
750 // Check the return type
751 const char* descriptor = raw->GetReturnTypeDescriptor(proto_id);
752 if (descriptor[0] == 'L' || descriptor[0] == '[') {
753 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
754 return false;
755 }
756 }
757 return true;
758}
759
760// Returns true if classes referenced by the descriptor are the
761// same classes in klass1 as they are in klass2.
762bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700763 const Class* klass1,
764 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700765 CHECK(descriptor != NULL);
766 CHECK(klass1 != NULL);
767 CHECK(klass2 != NULL);
768#if 0
769 Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader());
770 // TODO: found1 == NULL
771 Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader());
772 // TODO: found2 == NULL
773 // TODO: lookup found1 in initiating loader list
774 if (found1 == NULL || found2 == NULL) {
Carl Shapirob5573532011-07-12 18:22:59 -0700775 Thread::Current()->ClearException();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700776 if (found1 == found2) {
777 return true;
778 } else {
779 return false;
780 }
781 }
782#endif
783 return true;
784}
785
786bool ClassLinker::InitializeSuperClass(Class* klass) {
787 CHECK(klass != NULL);
788 // TODO: assert klass lock is acquired
789 if (!klass->IsInterface() && klass->HasSuperClass()) {
790 Class* super_class = klass->GetSuperClass();
791 if (super_class->GetStatus() != Class::kStatusInitialized) {
792 CHECK(!super_class->IsInterface());
793 klass->MonitorExit();
794 bool super_initialized = InitializeClass(super_class);
795 klass->MonitorEnter();
796 // TODO: check for a pending exception
797 if (!super_initialized) {
798 klass->SetStatus(Class::kStatusError);
799 klass->NotifyAll();
800 return false;
801 }
802 }
803 }
804 return true;
805}
806
807void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700808 size_t num_static_fields = klass->NumStaticFields();
809 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700810 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700811 }
812 DexFile* dex_file = klass->GetDexFile();
813 if (dex_file == NULL) {
814 return;
815 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700816 const StringPiece& descriptor = klass->GetDescriptor();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700817 const RawDexFile* raw = dex_file->GetRaw();
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700818 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
819 CHECK(class_def != NULL);
820 const byte* addr = raw->GetEncodedArray(*class_def);
821 size_t array_size = DecodeUnsignedLeb128(&addr);
822 for (size_t i = 0; i < array_size; ++i) {
823 StaticField* field = klass->GetStaticField(i);
824 JValue value;
825 RawDexFile::ValueType type = raw->ReadEncodedValue(&addr, &value);
826 switch (type) {
827 case RawDexFile::kByte:
828 field->SetByte(value.b);
829 break;
830 case RawDexFile::kShort:
831 field->SetShort(value.s);
832 break;
833 case RawDexFile::kChar:
834 field->SetChar(value.c);
835 break;
836 case RawDexFile::kInt:
837 field->SetInt(value.i);
838 break;
839 case RawDexFile::kLong:
840 field->SetLong(value.j);
841 break;
842 case RawDexFile::kFloat:
843 field->SetFloat(value.f);
844 break;
845 case RawDexFile::kDouble:
846 field->SetDouble(value.d);
847 break;
848 case RawDexFile::kString: {
849 uint32_t string_idx = value.i;
850 String* resolved = ResolveString(klass, string_idx);
851 field->SetObject(resolved);
852 break;
853 }
854 case RawDexFile::kBoolean:
855 field->SetBoolean(value.z);
856 break;
857 case RawDexFile::kNull:
858 field->SetObject(value.l);
859 break;
860 default:
Carl Shapiro606258b2011-07-09 16:09:09 -0700861 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700862 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700863 }
864}
865
866bool ClassLinker::LinkClass(Class* klass) {
867 CHECK(klass->status_ == Class::kStatusIdx ||
868 klass->status_ == Class::kStatusLoaded);
869 if (klass->status_ == Class::kStatusIdx) {
870 if (!LinkInterfaces(klass)) {
871 return false;
872 }
873 }
874 if (!LinkSuperClass(klass)) {
875 return false;
876 }
877 if (!LinkMethods(klass)) {
878 return false;
879 }
880 if (!LinkInstanceFields(klass)) {
881 return false;
882 }
883 CreateReferenceOffsets(klass);
884 CHECK_EQ(klass->status_, Class::kStatusLoaded);
885 klass->status_ = Class::kStatusResolved;
886 return true;
887}
888
889bool ClassLinker::LinkInterfaces(Class* klass) {
890 scoped_array<uint32_t> interfaces_idx;
891 // TODO: store interfaces_idx in the Class object
892 // TODO: move this outside of link interfaces
893 if (klass->interface_count_ > 0) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700894 size_t length = klass->interface_count_ * sizeof(klass->interfaces_[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700895 interfaces_idx.reset(new uint32_t[klass->interface_count_]);
Carl Shapiro565f5072011-07-10 13:39:43 -0700896 memcpy(interfaces_idx.get(), klass->interfaces_, length);
897 memset(klass->interfaces_, 0xFF, length);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700898 }
899 // Mark the class as loaded.
900 klass->status_ = Class::kStatusLoaded;
901 if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
902 Class* super_class = ResolveClass(klass, klass->super_class_idx_);
903 if (super_class == NULL) {
904 LG << "Failed to resolve superclass";
905 return false;
906 }
907 klass->super_class_ = super_class; // TODO: write barrier
908 }
909 if (klass->interface_count_ > 0) {
910 for (size_t i = 0; i < klass->interface_count_; ++i) {
911 uint32_t idx = interfaces_idx[i];
912 klass->interfaces_[i] = ResolveClass(klass, idx);
913 if (klass->interfaces_[i] == NULL) {
914 LG << "Failed to resolve interface";
915 return false;
916 }
917 // Verify
918 if (!klass->CanAccess(klass->interfaces_[i])) {
919 LG << "Inaccessible interface";
920 return false;
921 }
922 }
923 }
924 return true;
925}
926
927bool ClassLinker::LinkSuperClass(Class* klass) {
928 CHECK(!klass->IsPrimitive());
929 const Class* super = klass->GetSuperClass();
930 if (klass->GetDescriptor() == "Ljava/lang/Object;") {
931 if (super != NULL) {
932 LG << "Superclass must not be defined"; // TODO: ClassFormatError
933 return false;
934 }
935 // TODO: clear finalize attribute
936 return true;
937 }
938 if (super == NULL) {
939 LG << "No superclass defined"; // TODO: LinkageError
940 return false;
941 }
942 // Verify
943 if (super->IsFinal()) {
944 LG << "Superclass is declared final"; // TODO: IncompatibleClassChangeError
945 return false;
946 }
947 if (super->IsInterface()) {
948 LG << "Superclass is an interface"; // TODO: IncompatibleClassChangeError
949 return false;
950 }
951 if (!klass->CanAccess(super)) {
952 LG << "Superclass is inaccessible"; // TODO: IllegalAccessError
953 return false;
954 }
955 return true;
956}
957
958// Populate the class vtable and itable.
959bool ClassLinker::LinkMethods(Class* klass) {
960 if (klass->IsInterface()) {
961 // No vtable.
962 size_t count = klass->NumVirtualMethods();
963 if (!IsUint(16, count)) {
964 LG << "Too many methods on interface"; // TODO: VirtualMachineError
965 return false;
966 }
Carl Shapiro565f5072011-07-10 13:39:43 -0700967 for (size_t i = 0; i < count; ++i) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700968 klass->GetVirtualMethod(i)->method_index_ = i;
969 }
970 } else {
971 // Link virtual method tables
972 LinkVirtualMethods(klass);
973
974 // Link interface method tables
975 LinkInterfaceMethods(klass);
976
977 // Insert stubs.
978 LinkAbstractMethods(klass);
979 }
980 return true;
981}
982
983bool ClassLinker::LinkVirtualMethods(Class* klass) {
984 uint32_t max_count = klass->NumVirtualMethods();
985 if (klass->GetSuperClass() != NULL) {
986 max_count += klass->GetSuperClass()->NumVirtualMethods();
987 } else {
988 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
989 }
990 // TODO: do not assign to the vtable field until it is fully constructed.
991 // TODO: make this a vector<Method*> instead?
992 klass->vtable_ = new Method*[max_count];
993 if (klass->HasSuperClass()) {
994 memcpy(klass->vtable_,
995 klass->GetSuperClass()->vtable_,
996 klass->GetSuperClass()->vtable_count_ * sizeof(Method*));
997 size_t actual_count = klass->GetSuperClass()->vtable_count_;
998 // See if any of our virtual methods override the superclass.
999 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1000 Method* local_method = klass->GetVirtualMethod(i);
1001 size_t j = 0;
1002 for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
1003 const Method* super_method = klass->vtable_[j];
1004 if (local_method->HasSameNameAndPrototype(super_method)) {
1005 // Verify
1006 if (super_method->IsFinal()) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001007 LG << "Method overrides final method"; // TODO: VirtualMachineError
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001008 return false;
1009 }
1010 klass->vtable_[j] = local_method;
1011 local_method->method_index_ = j;
1012 break;
1013 }
1014 }
1015 if (j == klass->GetSuperClass()->vtable_count_) {
1016 // Not overriding, append.
1017 klass->vtable_[actual_count] = local_method;
1018 local_method->method_index_ = actual_count;
1019 actual_count += 1;
1020 }
1021 }
1022 if (!IsUint(16, actual_count)) {
1023 LG << "Too many methods defined on class"; // TODO: VirtualMachineError
1024 return false;
1025 }
1026 CHECK_LE(actual_count, max_count);
1027 if (actual_count < max_count) {
1028 Method** new_vtable = new Method*[actual_count];
1029 memcpy(new_vtable, klass->vtable_, actual_count * sizeof(Method*));
Carl Shapiro565f5072011-07-10 13:39:43 -07001030 delete[] klass->vtable_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001031 klass->vtable_ = new_vtable;
1032 LG << "shrunk vtable: "
1033 << "was " << max_count << ", "
1034 << "now " << actual_count;
1035 }
1036 klass->vtable_count_ = actual_count;
1037 } else {
1038 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
1039 if (!IsUint(16, klass->NumVirtualMethods())) {
1040 LG << "Too many methods"; // TODO: VirtualMachineError
1041 return false;
1042 }
1043 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1044 klass->vtable_[i] = klass->GetVirtualMethod(i);
1045 klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
1046 }
1047 klass->vtable_count_ = klass->NumVirtualMethods();
1048 }
1049 return true;
1050}
1051
1052bool ClassLinker::LinkInterfaceMethods(Class* klass) {
1053 int pool_offset = 0;
1054 int pool_size = 0;
1055 int miranda_count = 0;
1056 int miranda_alloc = 0;
1057 size_t super_ifcount;
1058 if (klass->HasSuperClass()) {
1059 super_ifcount = klass->GetSuperClass()->iftable_count_;
1060 } else {
1061 super_ifcount = 0;
1062 }
1063 size_t ifCount = super_ifcount;
1064 ifCount += klass->interface_count_;
1065 for (size_t i = 0; i < klass->interface_count_; i++) {
1066 ifCount += klass->interfaces_[i]->iftable_count_;
1067 }
1068 if (ifCount == 0) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001069 DCHECK(klass->iftable_count_ == 0);
1070 DCHECK(klass->iftable_ == NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001071 return true;
1072 }
1073 klass->iftable_ = new InterfaceEntry[ifCount * sizeof(InterfaceEntry)];
1074 memset(klass->iftable_, 0x00, sizeof(InterfaceEntry) * ifCount);
1075 if (super_ifcount != 0) {
1076 memcpy(klass->iftable_, klass->GetSuperClass()->iftable_,
1077 sizeof(InterfaceEntry) * super_ifcount);
1078 }
1079 // Flatten the interface inheritance hierarchy.
1080 size_t idx = super_ifcount;
1081 for (size_t i = 0; i < klass->interface_count_; i++) {
1082 Class* interf = klass->interfaces_[i];
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001083 DCHECK(interf != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001084 if (!interf->IsInterface()) {
1085 LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
1086 return false;
1087 }
1088 klass->iftable_[idx++].SetClass(interf);
1089 for (size_t j = 0; j < interf->iftable_count_; j++) {
1090 klass->iftable_[idx++].SetClass(interf->iftable_[j].GetClass());
1091 }
1092 }
1093 CHECK_EQ(idx, ifCount);
1094 klass->iftable_count_ = ifCount;
1095 if (klass->IsInterface() || super_ifcount == ifCount) {
1096 return true;
1097 }
1098 for (size_t i = super_ifcount; i < ifCount; i++) {
1099 pool_size += klass->iftable_[i].GetClass()->NumVirtualMethods();
1100 }
1101 if (pool_size == 0) {
1102 return true;
1103 }
1104 klass->ifvi_pool_count_ = pool_size;
1105 klass->ifvi_pool_ = new uint32_t[pool_size];
1106 std::vector<Method*> miranda_list;
1107 for (size_t i = super_ifcount; i < ifCount; ++i) {
1108 klass->iftable_[i].method_index_array_ = klass->ifvi_pool_ + pool_offset;
1109 Class* interface = klass->iftable_[i].GetClass();
1110 pool_offset += interface->NumVirtualMethods(); // end here
1111 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
1112 Method* interface_method = interface->GetVirtualMethod(j);
1113 int k; // must be signed
1114 for (k = klass->vtable_count_ - 1; k >= 0; --k) {
1115 if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) {
Carl Shapiro565f5072011-07-10 13:39:43 -07001116 if (!klass->vtable_[k]->IsPublic()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001117 LG << "Implementation not public";
1118 return false;
1119 }
1120 klass->iftable_[i].method_index_array_[j] = k;
1121 break;
1122 }
1123 }
1124 if (k < 0) {
1125 if (miranda_count == miranda_alloc) {
1126 miranda_alloc += 8;
1127 if (miranda_list.empty()) {
1128 miranda_list.resize(miranda_alloc);
1129 } else {
1130 miranda_list.resize(miranda_alloc);
1131 }
1132 }
1133 int mir;
1134 for (mir = 0; mir < miranda_count; mir++) {
1135 if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) {
1136 break;
1137 }
1138 }
1139 // point the interface table at a phantom slot index
1140 klass->iftable_[i].method_index_array_[j] = klass->vtable_count_ + mir;
1141 if (mir == miranda_count) {
1142 miranda_list[miranda_count++] = interface_method;
1143 }
1144 }
1145 }
1146 }
1147 if (miranda_count != 0) {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001148 int oldMethodCount = klass->NumVirtualMethods();
1149 int newMethodCount = oldMethodCount + miranda_count;
1150 Method** newVirtualMethods = new Method*[newMethodCount];
1151 if (klass->virtual_methods_ != NULL) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001152 memcpy(newVirtualMethods,
1153 klass->virtual_methods_,
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001154 klass->NumVirtualMethods() * sizeof(Method*));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001155 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001156 klass->virtual_methods_ = newVirtualMethods;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001157 klass->num_virtual_methods_ = newMethodCount;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001158
1159 CHECK(klass->vtable_ != NULL);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001160 int oldVtableCount = klass->vtable_count_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001161 klass->vtable_count_ += miranda_count;
1162
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001163 for (int i = 0; i < miranda_count; i++) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001164 Method* meth = AllocMethod();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001165 memcpy(meth, miranda_list[i], sizeof(Method));
1166 meth->klass_ = klass;
1167 meth->access_flags_ |= kAccMiranda;
1168 meth->method_index_ = 0xFFFF & (oldVtableCount + i);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001169 klass->virtual_methods_[oldMethodCount+i] = meth;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001170 klass->vtable_[oldVtableCount + i] = meth;
1171 }
1172 }
1173 return true;
1174}
1175
1176void ClassLinker::LinkAbstractMethods(Class* klass) {
1177 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1178 Method* method = klass->GetVirtualMethod(i);
1179 if (method->IsAbstract()) {
1180 method->insns_ = reinterpret_cast<uint16_t*>(0xFFFFFFFF); // TODO: AbstractMethodError
1181 }
1182 }
1183}
1184
1185bool ClassLinker::LinkInstanceFields(Class* klass) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001186 int field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001187 if (klass->GetSuperClass() != NULL) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001188 field_offset = klass->GetSuperClass()->object_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001189 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -07001190 field_offset = OFFSETOF_MEMBER(DataObject, fields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001191 }
1192 // Move references to the front.
1193 klass->num_reference_ifields_ = 0;
1194 size_t i = 0;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001195 for ( ; i < klass->NumInstanceFields(); i++) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001196 InstanceField* pField = klass->GetInstanceField(i);
1197 char c = pField->GetType();
1198
1199 if (c != '[' && c != 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001200 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1201 InstanceField* refField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001202 char rc = refField->GetType();
1203 if (rc == '[' || rc == 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001204 klass->SetInstanceField(i, refField);
1205 klass->SetInstanceField(j, pField);
1206 pField = refField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001207 c = rc;
1208 klass->num_reference_ifields_++;
1209 break;
1210 }
1211 }
1212 } else {
1213 klass->num_reference_ifields_++;
1214 }
1215 if (c != '[' && c != 'L') {
1216 break;
1217 }
Brian Carlstroma0808032011-07-18 00:39:23 -07001218 pField->SetOffset(field_offset);
1219 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001220 }
1221
1222 // Now we want to pack all of the double-wide fields together. If
1223 // we're not aligned, though, we want to shuffle one 32-bit field
1224 // into place. If we can't find one, we'll have to pad it.
Brian Carlstroma0808032011-07-18 00:39:23 -07001225 if (i != klass->NumInstanceFields() && (field_offset & 0x04) != 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001226 InstanceField* pField = klass->GetInstanceField(i);
1227 char c = pField->GetType();
1228
1229 if (c != 'J' && c != 'D') {
1230 // The field that comes next is 32-bit, so just advance past it.
Brian Carlstrombe977852011-07-19 14:54:54 -07001231 DCHECK(c != '[');
1232 DCHECK(c != 'L');
Brian Carlstroma0808032011-07-18 00:39:23 -07001233 pField->SetOffset(field_offset);
1234 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001235 i++;
1236 } else {
1237 // Next field is 64-bit, so search for a 32-bit field we can
1238 // swap into it.
1239 bool found = false;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001240 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1241 InstanceField* singleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001242 char rc = singleField->GetType();
1243 if (rc != 'J' && rc != 'D') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001244 klass->SetInstanceField(i, singleField);
1245 klass->SetInstanceField(j, pField);
1246 pField = singleField;
Brian Carlstroma0808032011-07-18 00:39:23 -07001247 pField->SetOffset(field_offset);
1248 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001249 found = true;
1250 i++;
1251 break;
1252 }
1253 }
1254 if (!found) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001255 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001256 }
1257 }
1258 }
1259
1260 // Alignment is good, shuffle any double-wide fields forward, and
1261 // finish assigning field offsets to all fields.
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001262 DCHECK(i == klass->NumInstanceFields() || (field_offset & 0x04) == 0);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001263 for ( ; i < klass->NumInstanceFields(); i++) {
1264 InstanceField* pField = klass->GetInstanceField(i);
1265 char c = pField->GetType();
1266 if (c != 'D' && c != 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001267 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1268 InstanceField* doubleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001269 char rc = doubleField->GetType();
1270 if (rc == 'D' || rc == 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001271 klass->SetInstanceField(i, doubleField);
1272 klass->SetInstanceField(j, pField);
1273 pField = doubleField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001274 c = rc;
1275 break;
1276 }
1277 }
1278 } else {
1279 // This is a double-wide field, leave it be.
1280 }
1281
Brian Carlstroma0808032011-07-18 00:39:23 -07001282 pField->SetOffset(field_offset);
1283 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001284 if (c == 'J' || c == 'D')
Brian Carlstroma0808032011-07-18 00:39:23 -07001285 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001286 }
1287
1288#ifndef NDEBUG
Brian Carlstrombe977852011-07-19 14:54:54 -07001289 // Make sure that all reference fields appear before
1290 // non-reference fields, and all double-wide fields are aligned.
1291 bool seen_non_ref = false;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001292 for (i = 0; i < klass->NumInstanceFields(); i++) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001293 InstanceField *pField = klass->GetInstanceField(i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001294 char c = pField->GetType();
1295
1296 if (c == 'D' || c == 'J') {
Brian Carlstrombe977852011-07-19 14:54:54 -07001297 DCHECK_EQ(0U, pField->GetOffset() & 0x07);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001298 }
1299
1300 if (c != '[' && c != 'L') {
Brian Carlstrombe977852011-07-19 14:54:54 -07001301 if (!seen_non_ref) {
1302 seen_non_ref = true;
1303 DCHECK_EQ(klass->num_reference_ifields_, i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001304 }
Brian Carlstrombe977852011-07-19 14:54:54 -07001305 } else {
1306 DCHECK(!seen_non_ref);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001307 }
1308 }
Brian Carlstrombe977852011-07-19 14:54:54 -07001309 if (!seen_non_ref) {
1310 DCHECK(klass->NumInstanceFields(), klass->num_reference_ifields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001311 }
1312#endif
1313
Brian Carlstroma0808032011-07-18 00:39:23 -07001314 klass->object_size_ = field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001315 return true;
1316}
1317
1318// Set the bitmap of reference offsets, refOffsets, from the ifields
1319// list.
1320void ClassLinker::CreateReferenceOffsets(Class* klass) {
1321 uint32_t reference_offsets = 0;
1322 if (klass->HasSuperClass()) {
1323 reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
1324 }
1325 // If our superclass overflowed, we don't stand a chance.
1326 if (reference_offsets != CLASS_WALK_SUPER) {
1327 // All of the fields that contain object references are guaranteed
1328 // to be at the beginning of the ifields list.
1329 for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
1330 // Note that, per the comment on struct InstField, f->byteOffset
1331 // is the offset from the beginning of obj, not the offset into
1332 // obj->instanceData.
1333 const InstanceField* field = klass->GetInstanceField(i);
1334 size_t byte_offset = field->GetOffset();
1335 CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001336 CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001337 if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
1338 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001339 CHECK_NE(new_bit, 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001340 reference_offsets |= new_bit;
1341 } else {
1342 reference_offsets = CLASS_WALK_SUPER;
1343 break;
1344 }
1345 }
1346 klass->SetReferenceOffsets(reference_offsets);
1347 }
1348}
1349
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001350Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001351 DexFile* dex_file = referrer->GetDexFile();
1352 Class* resolved = dex_file->GetResolvedClass(class_idx);
1353 if (resolved != NULL) {
1354 return resolved;
1355 }
1356 const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx);
1357 if (descriptor[0] != '\0' && descriptor[1] == '\0') {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001358 resolved = FindPrimitiveClass(descriptor[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001359 } else {
Brian Carlstrom6cc18452011-07-18 15:10:33 -07001360 resolved = FindClass(descriptor, referrer->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001361 }
1362 if (resolved != NULL) {
1363 Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
1364 if (referrer->GetDexFile() != check->GetDexFile()) {
1365 if (check->GetClassLoader() != NULL) {
1366 LG << "Class resolved by unexpected DEX"; // TODO: IllegalAccessError
1367 return NULL;
1368 }
1369 }
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001370 dex_file->SetResolvedClass(resolved, class_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001371 } else {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001372 DCHECK(Thread::Current()->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001373 }
1374 return resolved;
1375}
1376
1377Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
1378 /*MethodType*/ int method_type) {
1379 CHECK(false);
1380 return NULL;
1381}
1382
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001383String* ClassLinker::ResolveString(const Class* referring, uint32_t string_idx) {
1384 const RawDexFile* raw = referring->GetDexFile()->GetRaw();
1385 const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
1386 const char* string_data = raw->GetStringData(string_id);
Brian Carlstroma0808032011-07-18 00:39:23 -07001387 String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_, char_array_class_, string_data);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001388 // TODO: intern the new string
1389 referring->GetDexFile()->SetResolvedString(new_string, string_idx);
1390 return new_string;
1391}
1392
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001393} // namespace art