blob: 39d3c25dcda4dbc3d43b0e2020b24061fa0939af [file] [log] [blame]
Carl Shapiro3ee755d2011-06-28 12:11:04 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07003#include "object.h"
4
Ian Rogersb033c752011-07-20 12:22:35 -07005#include <string.h>
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07006
Ian Rogersdf20fe02011-07-20 20:34:16 -07007#include <algorithm>
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07008#include <string>
9#include <utility>
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070010
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070011#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070012#include "class_loader.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070013#include "globals.h"
Brian Carlstroma40f9bc2011-07-26 21:26:07 -070014#include "heap.h"
Elliott Hughescf4c6c42011-09-01 15:16:42 -070015#include "intern_table.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070016#include "logging.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070017#include "dex_cache.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070018#include "dex_file.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070019#include "runtime.h"
Carl Shapiro3ee755d2011-06-28 12:11:04 -070020
21namespace art {
22
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070023bool Object::IsString() const {
24 // TODO use "klass_ == String::GetJavaLangString()" instead?
25 return GetClass() == GetClass()->GetDescriptor()->GetClass();
26}
27
28// TODO: get global references for these
29Class* Field::java_lang_reflect_Field_ = NULL;
30
31void Field::SetClass(Class* java_lang_reflect_Field) {
32 CHECK(java_lang_reflect_Field_ == NULL);
33 CHECK(java_lang_reflect_Field != NULL);
34 java_lang_reflect_Field_ = java_lang_reflect_Field;
35}
36
37void Field::ResetClass() {
38 CHECK(java_lang_reflect_Field_ != NULL);
39 java_lang_reflect_Field_ = NULL;
40}
41
42void Field::SetTypeIdx(uint32_t type_idx) {
43 SetField32(OFFSET_OF_OBJECT_MEMBER(Field, type_idx_), type_idx, false);
44}
45
46Class* Field::GetTypeDuringLinking() const {
47 // We are assured that the necessary primitive types are in the dex cache
48 // early during class linking
49 return GetDeclaringClass()->GetDexCache()->GetResolvedType(GetTypeIdx());
50}
51
52Class* Field::GetType() const {
53 DCHECK(Runtime::Current() != NULL)
54 << "Can't call GetType without an initialized runtime";
55 // Do full linkage (which sets dex cache value to speed next call)
56 return Runtime::Current()->GetClassLinker()->ResolveType(GetTypeIdx(), this);
57}
58
59uint32_t Field::Get32StaticFromCode(uint32_t field_idx, const Method* referrer) {
60 Field* field = Runtime::Current()->GetClassLinker()->ResolveField(field_idx, referrer);
61 if (field == NULL) {
62 UNIMPLEMENTED(FATAL) << "throw an error";
63 return 0;
Brian Carlstromb63ec392011-08-27 17:38:27 -070064 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070065 DCHECK(field->GetType()->PrimitiveSize() == sizeof(int32_t));
66 return field->Get32(NULL);
67}
68void Field::Set32StaticFromCode(uint32_t field_idx, const Method* referrer, uint32_t new_value) {
69 Field* field = Runtime::Current()->GetClassLinker()->ResolveField(field_idx, referrer);
70 if (field == NULL) {
71 UNIMPLEMENTED(FATAL) << "throw an error";
72 return;
73 }
74 DCHECK(field->GetType()->PrimitiveSize() == sizeof(int32_t));
75 field->Set32(NULL, new_value);
76}
77uint64_t Field::Get64StaticFromCode(uint32_t field_idx, const Method* referrer) {
78 Field* field = Runtime::Current()->GetClassLinker()->ResolveField(field_idx, referrer);
79 if (field == NULL) {
80 UNIMPLEMENTED(FATAL) << "throw an error";
81 return 0;
82 }
83 DCHECK(field->GetType()->PrimitiveSize() == sizeof(int64_t));
84 return field->Get64(NULL);
85}
86void Field::Set64StaticFromCode(uint32_t field_idx, const Method* referrer, uint64_t new_value) {
87 Field* field = Runtime::Current()->GetClassLinker()->ResolveField(field_idx, referrer);
88 if (field == NULL) {
89 UNIMPLEMENTED(FATAL) << "throw an error";
90 return;
91 }
92 DCHECK(field->GetType()->PrimitiveSize() == sizeof(int64_t));
93 field->Set64(NULL, new_value);
94}
95Object* Field::GetObjStaticFromCode(uint32_t field_idx, const Method* referrer) {
96 Field* field = Runtime::Current()->GetClassLinker()->ResolveField(field_idx, referrer);
97 if (field == NULL) {
98 UNIMPLEMENTED(FATAL) << "throw an error";
99 return 0;
100 }
101 DCHECK(!field->GetType()->IsPrimitive());
102 return field->GetObj(NULL);
103}
104void Field::SetObjStaticFromCode(uint32_t field_idx, const Method* referrer, Object* new_value) {
105 Field* field = Runtime::Current()->GetClassLinker()->ResolveField(field_idx, referrer);
106 if (field == NULL) {
107 UNIMPLEMENTED(FATAL) << "throw an error";
108 return;
109 }
110 DCHECK(!field->GetType()->IsPrimitive());
111 field->SetObj(NULL, new_value);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700112}
113
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700114uint32_t Field::Get32(const Object* object) const {
115 CHECK((object == NULL) == IsStatic());
116 if (IsStatic()) {
117 object = declaring_class_;
118 }
119 return object->GetField32(GetOffset(), IsVolatile());
Elliott Hughes68f4fa02011-08-21 10:46:59 -0700120}
121
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700122void Field::Set32(Object* object, uint32_t new_value) const {
123 CHECK((object == NULL) == IsStatic());
124 if (IsStatic()) {
125 object = declaring_class_;
126 }
127 object->SetField32(GetOffset(), new_value, IsVolatile());
128}
129
130uint64_t Field::Get64(const Object* object) const {
131 CHECK((object == NULL) == IsStatic());
132 if (IsStatic()) {
133 object = declaring_class_;
134 }
135 return object->GetField64(GetOffset(), IsVolatile());
136}
137
138void Field::Set64(Object* object, uint64_t new_value) const {
139 CHECK((object == NULL) == IsStatic());
140 if (IsStatic()) {
141 object = declaring_class_;
142 }
143 object->SetField64(GetOffset(), new_value, IsVolatile());
144}
145
146Object* Field::GetObj(const Object* object) const {
147 CHECK((object == NULL) == IsStatic());
148 if (IsStatic()) {
149 object = declaring_class_;
150 }
151 return object->GetFieldObject<Object*>(GetOffset(), IsVolatile());
152}
153
154void Field::SetObj(Object* object, const Object* new_value) const {
155 CHECK((object == NULL) == IsStatic());
156 if (IsStatic()) {
157 object = declaring_class_;
158 }
159 object->SetFieldObject(GetOffset(), new_value, IsVolatile());
160}
161
162bool Field::GetBoolean(const Object* object) const {
163 DCHECK(GetType()->IsPrimitiveBoolean());
164 return Get32(object);
165}
166
167void Field::SetBoolean(Object* object, bool z) const {
168 DCHECK(GetType()->IsPrimitiveBoolean());
169 Set32(object, z);
170}
171
172int8_t Field::GetByte(const Object* object) const {
173 DCHECK(GetType()->IsPrimitiveByte());
174 return Get32(object);
175}
176
177void Field::SetByte(Object* object, int8_t b) const {
178 DCHECK(GetType()->IsPrimitiveByte());
179 Set32(object, b);
180}
181
182uint16_t Field::GetChar(const Object* object) const {
183 DCHECK(GetType()->IsPrimitiveChar());
184 return Get32(object);
185}
186
187void Field::SetChar(Object* object, uint16_t c) const {
188 DCHECK(GetType()->IsPrimitiveChar());
189 Set32(object, c);
190}
191
192uint16_t Field::GetShort(const Object* object) const {
193 DCHECK(GetType()->IsPrimitiveShort());
194 return Get32(object);
195}
196
197void Field::SetShort(Object* object, uint16_t s) const {
198 DCHECK(GetType()->IsPrimitiveShort());
199 Set32(object, s);
200}
201
202int32_t Field::GetInt(const Object* object) const {
203 DCHECK(GetType()->IsPrimitiveInt());
204 return Get32(object);
205}
206
207void Field::SetInt(Object* object, int32_t i) const {
208 DCHECK(GetType()->IsPrimitiveInt());
209 Set32(object, i);
210}
211
212int64_t Field::GetLong(const Object* object) const {
213 DCHECK(GetType()->IsPrimitiveLong());
214 return Get64(object);
215}
216
217void Field::SetLong(Object* object, int64_t j) const {
218 DCHECK(GetType()->IsPrimitiveLong());
219 Set64(object, j);
220}
221
222float Field::GetFloat(const Object* object) const {
223 DCHECK(GetType()->IsPrimitiveFloat());
224 JValue float_bits;
225 float_bits.i = Get32(object);
226 return float_bits.f;
227}
228
229void Field::SetFloat(Object* object, float f) const {
230 DCHECK(GetType()->IsPrimitiveFloat());
231 JValue float_bits;
232 float_bits.f = f;
233 Set32(object, float_bits.i);
234}
235
236double Field::GetDouble(const Object* object) const {
237 DCHECK(GetType()->IsPrimitiveDouble());
238 JValue double_bits;
239 double_bits.j = Get64(object);
240 return double_bits.d;
241}
242
243void Field::SetDouble(Object* object, double d) const {
244 DCHECK(GetType()->IsPrimitiveDouble());
245 JValue double_bits;
246 double_bits.d = d;
247 Set64(object, double_bits.j);
248}
249
250Object* Field::GetObject(const Object* object) const {
251 CHECK(!GetType()->IsPrimitive());
252 return GetObj(object);
253}
254
255void Field::SetObject(Object* object, const Object* l) const {
256 CHECK(!GetType()->IsPrimitive());
257 SetObj(object, l);
258}
259
260// TODO: get global references for these
261Class* Method::java_lang_reflect_Method_ = NULL;
262
263void Method::SetClass(Class* java_lang_reflect_Method) {
264 CHECK(java_lang_reflect_Method_ == NULL);
265 CHECK(java_lang_reflect_Method != NULL);
266 java_lang_reflect_Method_ = java_lang_reflect_Method;
267}
268
269void Method::ResetClass() {
270 CHECK(java_lang_reflect_Method_ != NULL);
271 java_lang_reflect_Method_ = NULL;
272}
273
274ObjectArray<String>* Method::GetDexCacheStrings() const {
275 return GetFieldObject<ObjectArray<String>*>(
276 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_strings_), false);
277}
278
279void Method::SetReturnTypeIdx(uint32_t new_return_type_idx) {
280 SetField32(OFFSET_OF_OBJECT_MEMBER(Method, java_return_type_idx_),
281 new_return_type_idx, false);
282}
283
284Class* Method::GetReturnType() const {
285 DCHECK(GetDeclaringClass()->IsLinked());
286 // Short-cut
287 Class* result = GetDexCacheResolvedTypes()->Get(GetReturnTypeIdx());
288 if (result == NULL) {
289 // Do full linkage and set cache value for next call
290 result = Runtime::Current()->GetClassLinker()->ResolveType(GetReturnTypeIdx(), this);
291 }
292 CHECK(result != NULL);
293 return result;
294}
295
296void Method::SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings) {
297 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_strings_),
298 new_dex_cache_strings, false);
299}
300
301ObjectArray<Class>* Method::GetDexCacheResolvedTypes() const {
302 return GetFieldObject<ObjectArray<Class>*>(
303 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_types_), false);
304}
305
306void Method::SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_classes) {
307 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_types_),
308 new_dex_cache_classes, false);
309}
310
311ObjectArray<Method>* Method::GetDexCacheResolvedMethods() const {
312 return GetFieldObject<ObjectArray<Method>*>(
313 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_), false);
314}
315
316void Method::SetDexCacheResolvedMethods(ObjectArray<Method>* new_dex_cache_methods) {
317 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_),
318 new_dex_cache_methods, false);
319}
320
321ObjectArray<Field>* Method::GetDexCacheResolvedFields() const {
322 return GetFieldObject<ObjectArray<Field>*>(
323 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_fields_), false);
324}
325
326void Method::SetDexCacheResolvedFields(ObjectArray<Field>* new_dex_cache_fields) {
327 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_fields_),
328 new_dex_cache_fields, false);
329}
330
331CodeAndDirectMethods* Method::GetDexCacheCodeAndDirectMethods() const {
332 return GetFieldPtr<CodeAndDirectMethods*>(
333 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_),
334 false);
335}
336
337void Method::SetDexCacheCodeAndDirectMethods(CodeAndDirectMethods* new_value) {
338 SetFieldPtr<CodeAndDirectMethods*>(
339 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_),
340 new_value, false);
341}
342
343ObjectArray<StaticStorageBase>* Method::GetDexCacheInitializedStaticStorage() const {
344 return GetFieldObject<ObjectArray<StaticStorageBase>*>(
345 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_initialized_static_storage_),
346 false);
347}
348
349void Method::SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value) {
350 SetFieldObject(
351 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_initialized_static_storage_),
352 new_value, false);
353
354}
355
356size_t Method::NumArgRegisters(const StringPiece& shorty) {
357 CHECK_LE(1, shorty.length());
358 uint32_t num_registers = 0;
359 for (int i = 1; i < shorty.length(); ++i) {
360 char ch = shorty[i];
361 if (ch == 'D' || ch == 'J') {
362 num_registers += 2;
363 } else {
364 num_registers += 1;
Brian Carlstromb63ec392011-08-27 17:38:27 -0700365 }
366 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700367 return num_registers;
368}
369
370size_t Method::NumArgArrayBytes() const {
371 const StringPiece& shorty = GetShorty();
372 size_t num_bytes = 0;
373 for (int i = 1; i < shorty.length(); ++i) {
374 char ch = shorty[i];
375 if (ch == 'D' || ch == 'J') {
376 num_bytes += 8;
377 } else if (ch == 'L') {
378 // Argument is a reference or an array. The shorty descriptor
379 // does not distinguish between these types.
380 num_bytes += sizeof(Object*);
381 } else {
382 num_bytes += 4;
383 }
384 }
385 return num_bytes;
386}
387
388// The number of reference arguments to this method including implicit this
389// pointer
390size_t Method::NumReferenceArgs() const {
391 const StringPiece& shorty = GetShorty();
392 size_t result = IsStatic() ? 0 : 1; // The implicit this pointer.
393 for (int i = 1; i < shorty.length(); i++) {
394 if ((shorty[i] == 'L') || (shorty[i] == '[')) {
395 result++;
396 }
397 }
398 return result;
399}
400
401// The number of long or double arguments
402size_t Method::NumLongOrDoubleArgs() const {
403 const StringPiece& shorty = GetShorty();
404 size_t result = 0;
405 for (int i = 1; i < shorty.length(); i++) {
406 if ((shorty[i] == 'D') || (shorty[i] == 'J')) {
407 result++;
408 }
409 }
410 return result;
411}
412
413// The number of reference arguments to this method before the given parameter
414// index
415size_t Method::NumReferenceArgsBefore(unsigned int param) const {
416 const StringPiece& shorty = GetShorty();
417 CHECK_LT(param, NumArgs());
418 unsigned int result = IsStatic() ? 0 : 1;
419 for (unsigned int i = 1; (i < (unsigned int)shorty.length()) &&
420 (i < (param + 1)); i++) {
421 if (shorty[i] == 'L') {
422 result++;
423 }
424 }
425 return result;
426}
427
428// Is the given method parameter a reference?
429bool Method::IsParamAReference(unsigned int param) const {
430 CHECK_LT(param, NumArgs());
431 if (IsStatic()) {
432 param++; // 0th argument must skip return value at start of the shorty
433 } else if (param == 0) {
434 return true; // this argument
435 }
436 return GetShorty()[param] == 'L';
437}
438
439// Is the given method parameter a long or double?
440bool Method::IsParamALongOrDouble(unsigned int param) const {
441 CHECK_LT(param, NumArgs());
442 if (IsStatic()) {
443 param++; // 0th argument must skip return value at start of the shorty
444 } else if (param == 0) {
445 return false; // this argument
446 }
447 return (GetShorty()[param] == 'J') || (GetShorty()[param] == 'D');
448}
449
450static size_t ShortyCharToSize(char x) {
451 switch (x) {
452 case 'V': return 0;
453 case '[': return kPointerSize;
454 case 'L': return kPointerSize;
455 case 'D': return 8;
456 case 'J': return 8;
457 default: return 4;
458 }
459}
460
461size_t Method::ParamSize(unsigned int param) const {
462 CHECK_LT(param, NumArgs());
463 if (IsStatic()) {
464 param++; // 0th argument must skip return value at start of the shorty
465 } else if (param == 0) {
466 return kPointerSize; // this argument
467 }
468 return ShortyCharToSize(GetShorty()[param]);
469}
470
471size_t Method::ReturnSize() const {
472 return ShortyCharToSize(GetShorty()[0]);
473}
474
475bool Method::HasSameNameAndDescriptor(const Method* that) const {
476 return (this->GetName()->Equals(that->GetName()) &&
477 this->GetSignature()->Equals(that->GetSignature()));
478}
479
480void Method::SetCode(const byte* compiled_code,
481 size_t byte_count,
482 InstructionSet set) {
483 // Copy the code into an executable region.
484 code_instruction_set_ = set;
485 code_area_.reset(MemMap::Map(byte_count,
486 PROT_READ | PROT_WRITE | PROT_EXEC));
487 CHECK(code_area_.get());
488 byte* code = code_area_->GetAddress();
489 memcpy(code, compiled_code, byte_count);
490 __builtin___clear_cache(code, code + byte_count);
491
492 uintptr_t address = reinterpret_cast<uintptr_t>(code);
493 if (code_instruction_set_ == kThumb2) {
494 // Set the low-order bit so a BLX will switch to Thumb mode
495 address |= 0x1;
496 }
497 SetFieldPtr<uintptr_t>(OFFSET_OF_OBJECT_MEMBER(Method, code_), address, false);
498}
499
500void Class::SetStatus(Status new_status) {
501 CHECK(new_status > GetStatus() || new_status == kStatusError ||
502 Runtime::Current() == NULL); // no runtime implies we're not initialized
503 CHECK(sizeof(Status) == sizeof(uint32_t));
504 return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_),
505 new_status, false);
506}
507
508DexCache* Class::GetDexCache() const {
509 return GetFieldObject<DexCache*>(
510 OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
511}
512
513void Class::SetDexCache(DexCache* new_dex_cache) {
514 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_),
515 new_dex_cache, false);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700516}
517
Brian Carlstrom1f870082011-08-23 16:02:11 -0700518Object* Class::AllocObjectFromCode(uint32_t type_idx, Method* method) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700519 Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700520 if (klass == NULL) {
521 klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
522 if (klass == NULL) {
523 UNIMPLEMENTED(FATAL) << "throw an error";
524 return NULL;
525 }
526 }
Brian Carlstrom1f870082011-08-23 16:02:11 -0700527 return klass->AllocObject();
528}
529
530Object* Class::AllocObject() {
531 DCHECK(!IsAbstract());
532 return Heap::AllocObject(this, this->object_size_);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700533}
534
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700535void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
536 if (new_reference_offsets != CLASS_WALK_SUPER) {
537 // Sanity check that the number of bits set in the reference offset bitmap
538 // agrees with the number of references
539 Class* cur = this;
540 size_t cnt = 0;
541 while (cur) {
542 cnt += cur->NumReferenceInstanceFieldsDuringLinking();
543 cur = cur->GetSuperClass();
544 }
545 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), cnt);
546 }
547 SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
548 new_reference_offsets, false);
549}
550
551void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
552 if (new_reference_offsets != CLASS_WALK_SUPER) {
553 // Sanity check that the number of bits set in the reference offset bitmap
554 // agrees with the number of references
555 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets),
556 NumReferenceStaticFieldsDuringLinking());
557 }
558 SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
559 new_reference_offsets, false);
560}
561
562size_t Class::PrimitiveSize() const {
563 switch (GetPrimitiveType()) {
564 case kPrimBoolean:
565 case kPrimByte:
566 case kPrimChar:
567 case kPrimShort:
568 case kPrimInt:
569 case kPrimFloat:
570 return sizeof(int32_t);
571 case kPrimLong:
572 case kPrimDouble:
573 return sizeof(int64_t);
574 default:
575 LOG(FATAL) << "Primitive type size calculation on invalid type " << this;
576 return 0;
577 }
578}
579
580size_t Class::GetTypeSize(const String* descriptor) {
581 switch (descriptor->CharAt(0)) {
582 case 'B': return 1; // byte
583 case 'C': return 2; // char
584 case 'D': return 8; // double
585 case 'F': return 4; // float
586 case 'I': return 4; // int
587 case 'J': return 8; // long
588 case 'S': return 2; // short
589 case 'Z': return 1; // boolean
590 case 'L': return sizeof(Object*);
591 case '[': return sizeof(Array*);
592 default:
593 LOG(ERROR) << "Unknown type " << descriptor;
594 return 0;
595 }
Elliott Hughesbf86d042011-08-31 17:53:14 -0700596}
597
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700598bool Class::Implements(const Class* klass) const {
599 DCHECK(klass != NULL);
600 DCHECK(klass->IsInterface());
601 // All interfaces implemented directly and by our superclass, and
602 // recursively all super-interfaces of those interfaces, are listed
603 // in iftable_, so we can just do a linear scan through that.
604 for (size_t i = 0; i < iftable_count_; i++) {
Brian Carlstrom30b94452011-08-25 21:35:26 -0700605 if (iftable_[i].GetInterface() == klass) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700606 return true;
607 }
608 }
609 return false;
610}
611
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700612bool Class::CanPutArrayElementFromCode(const Class* elementClass, const Class* arrayClass) {
613 UNIMPLEMENTED(FATAL);
614 return false;
615}
616
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700617// Determine whether "this" is assignable from "klazz", where both of these
618// are array classes.
619//
620// Consider an array class, e.g. Y[][], where Y is a subclass of X.
621// Y[][] = Y[][] --> true (identity)
622// X[][] = Y[][] --> true (element superclass)
623// Y = Y[][] --> false
624// Y[] = Y[][] --> false
625// Object = Y[][] --> true (everything is an object)
626// Object[] = Y[][] --> true
627// Object[][] = Y[][] --> true
628// Object[][][] = Y[][] --> false (too many []s)
629// Serializable = Y[][] --> true (all arrays are Serializable)
630// Serializable[] = Y[][] --> true
631// Serializable[][] = Y[][] --> false (unless Y is Serializable)
632//
633// Don't forget about primitive types.
634// int[] instanceof Object[] --> false
635//
636bool Class::IsArrayAssignableFromArray(const Class* klass) const {
Brian Carlstromb63ec392011-08-27 17:38:27 -0700637 DCHECK(IsArrayClass());
638 DCHECK(klass->IsArrayClass());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700639 DCHECK_GT(GetArrayRank(), 0);
640 DCHECK_GT(klass->GetArrayRank(), 0);
641 DCHECK(GetComponentType() != NULL);
642 DCHECK(klass->GetComponentType() != NULL);
643 if (GetArrayRank() > klass->GetArrayRank()) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700644 // Too many []s.
645 return false;
646 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700647 if (GetArrayRank() == klass->GetArrayRank()) {
648 return GetComponentType()->IsAssignableFrom(klass->GetComponentType());
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700649 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700650 DCHECK_LT(GetArrayRank(), klass->GetArrayRank());
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700651 // The thing we might be assignable from has more dimensions. We
652 // must be an Object or array of Object, or a standard array
653 // interface or array of standard array interfaces (the standard
654 // interfaces being java/lang/Cloneable and java/io/Serializable).
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700655 if (GetComponentType()->IsInterface()) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700656 // See if we implement our component type. We know the
657 // base element is an interface; if the array class implements
658 // it, we know it's a standard array interface.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700659 return Implements(GetComponentType());
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700660 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700661 // See if this is an array of Object, Object[], etc.
662 return GetComponentType()->IsObjectClass();
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700663}
664
665bool Class::IsAssignableFromArray(const Class* klass) const {
666 DCHECK(!IsInterface()); // handled first in IsAssignableFrom
Brian Carlstromb63ec392011-08-27 17:38:27 -0700667 DCHECK(klass->IsArrayClass());
668 if (!IsArrayClass()) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700669 // If "this" is not also an array, it must be Object.
670 // klass's super should be java_lang_Object, since it is an array.
671 Class* java_lang_Object = klass->GetSuperClass();
672 DCHECK(java_lang_Object != NULL);
673 DCHECK(java_lang_Object->GetSuperClass() == NULL);
674 return this == java_lang_Object;
675 }
676 return IsArrayAssignableFromArray(klass);
677}
678
679bool Class::IsSubClass(const Class* klass) const {
680 DCHECK(!IsInterface());
Brian Carlstromb63ec392011-08-27 17:38:27 -0700681 DCHECK(!klass->IsArrayClass());
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700682 const Class* current = this;
683 do {
684 if (current == klass) {
685 return true;
686 }
687 current = current->GetSuperClass();
688 } while (current != NULL);
689 return false;
690}
691
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700692bool Class::IsInSamePackage(const String* descriptor_string_1,
693 const String* descriptor_string_2) {
694 const std::string descriptor1(descriptor_string_1->ToModifiedUtf8());
695 const std::string descriptor2(descriptor_string_2->ToModifiedUtf8());
696
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700697 size_t i = 0;
698 while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
699 ++i;
700 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700701 if (descriptor1.find('/', i) != StringPiece::npos ||
702 descriptor2.find('/', i) != StringPiece::npos) {
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700703 return false;
704 } else {
705 return true;
706 }
707}
708
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700709#if 0
Ian Rogersb033c752011-07-20 12:22:35 -0700710bool Class::IsInSamePackage(const StringPiece& descriptor1,
711 const StringPiece& descriptor2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700712 size_t size = std::min(descriptor1.size(), descriptor2.size());
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700713 std::pair<StringPiece::const_iterator, StringPiece::const_iterator> pos;
Ian Rogersb033c752011-07-20 12:22:35 -0700714 pos = std::mismatch(descriptor1.begin(), descriptor1.begin() + size,
715 descriptor2.begin());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700716 return !(*(pos.second).rfind('/') != npos && descriptor2.rfind('/') != npos);
717}
718#endif
719
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700720bool Class::IsInSamePackage(const Class* that) const {
721 const Class* klass1 = this;
722 const Class* klass2 = that;
723 if (klass1 == klass2) {
724 return true;
725 }
726 // Class loaders must match.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700727 if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700728 return false;
729 }
730 // Arrays are in the same package when their element classes are.
Brian Carlstromb63ec392011-08-27 17:38:27 -0700731 if (klass1->IsArrayClass()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700732 klass1 = klass1->GetComponentType();
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700733 }
Brian Carlstromb63ec392011-08-27 17:38:27 -0700734 if (klass2->IsArrayClass()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700735 klass2 = klass2->GetComponentType();
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700736 }
737 // Compare the package part of the descriptor string.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700738 return IsInSamePackage(klass1->descriptor_, klass2->descriptor_);
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700739}
740
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700741const ClassLoader* Class::GetClassLoader() const {
742 return GetFieldObject<const ClassLoader*>(
743 OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
Brian Carlstromb9edb842011-08-28 16:31:06 -0700744}
745
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700746void Class::SetClassLoader(const ClassLoader* new_cl) {
747 ClassLoader* new_class_loader = const_cast<ClassLoader*>(new_cl);
748 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_),
749 new_class_loader, false);
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700750}
751
Brian Carlstrom30b94452011-08-25 21:35:26 -0700752Method* Class::FindVirtualMethodForInterface(Method* method) {
753 Class* declaring_class = method->GetDeclaringClass();
754 DCHECK(declaring_class->IsInterface());
755 // TODO cache to improve lookup speed
756 for (size_t i = 0; i < iftable_count_; i++) {
757 InterfaceEntry& interface_entry = iftable_[i];
758 if (interface_entry.GetInterface() == declaring_class) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700759 return GetVTable()->Get(
760 interface_entry.GetMethodIndexArray()[method->GetMethodIndex()]);
Brian Carlstrom30b94452011-08-25 21:35:26 -0700761 }
762 }
763 UNIMPLEMENTED(FATAL) << "Need to throw an error of some kind";
764 return NULL;
765}
766
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700767Method* Class::FindDeclaredDirectMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700768 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700769 for (size_t i = 0; i < NumDirectMethods(); ++i) {
Ian Rogersb033c752011-07-20 12:22:35 -0700770 Method* method = GetDirectMethod(i);
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700771 if (method->GetName()->Equals(name) &&
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700772 method->GetSignature()->Equals(signature)) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700773 return method;
Ian Rogersb033c752011-07-20 12:22:35 -0700774 }
775 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700776 return NULL;
Ian Rogersb033c752011-07-20 12:22:35 -0700777}
778
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700779Method* Class::FindDirectMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700780 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700781 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700782 Method* method = klass->FindDeclaredDirectMethod(name, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700783 if (method != NULL) {
784 return method;
785 }
786 }
787 return NULL;
788}
789
790Method* Class::FindDeclaredVirtualMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700791 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700792 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
Ian Rogersb033c752011-07-20 12:22:35 -0700793 Method* method = GetVirtualMethod(i);
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700794 if (method->GetName()->Equals(name) &&
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700795 method->GetSignature()->Equals(signature)) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700796 return method;
Ian Rogersb033c752011-07-20 12:22:35 -0700797 }
798 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700799 return NULL;
Ian Rogersb033c752011-07-20 12:22:35 -0700800}
801
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700802Method* Class::FindVirtualMethod(const StringPiece& name,
803 const StringPiece& descriptor) {
804 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
805 Method* method = klass->FindDeclaredVirtualMethod(name, descriptor);
806 if (method != NULL) {
807 return method;
808 }
809 }
810 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700811}
812
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700813Field* Class::FindDeclaredInstanceField(const StringPiece& name, Class* type) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700814 // Is the field in this class?
815 // Interfaces are not relevant because they can't contain instance fields.
816 for (size_t i = 0; i < NumInstanceFields(); ++i) {
817 Field* f = GetInstanceField(i);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700818 if (f->GetName()->Equals(name) && type == f->GetType()) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700819 return f;
820 }
821 }
822 return NULL;
823}
824
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700825Field* Class::FindInstanceField(const StringPiece& name, Class* type) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700826 // Is the field in this class, or any of its superclasses?
827 // Interfaces are not relevant because they can't contain instance fields.
828 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700829 Field* f = c->FindDeclaredInstanceField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -0700830 if (f != NULL) {
831 return f;
832 }
833 }
834 return NULL;
835}
836
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700837Field* Class::FindDeclaredStaticField(const StringPiece& name, Class* type) {
838 DCHECK(type != NULL);
Elliott Hughescdf53122011-08-19 15:46:09 -0700839 for (size_t i = 0; i < NumStaticFields(); ++i) {
840 Field* f = GetStaticField(i);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700841 if (f->GetName()->Equals(name) && f->GetType() == type) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700842 return f;
843 }
844 }
845 return NULL;
846}
847
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700848Field* Class::FindStaticField(const StringPiece& name, Class* type) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700849 // Is the field in this class (or its interfaces), or any of its
850 // superclasses (or their interfaces)?
851 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
852 // Is the field in this class?
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700853 Field* f = c->FindDeclaredStaticField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -0700854 if (f != NULL) {
855 return f;
856 }
857
858 // Is this field in any of this class' interfaces?
859 for (size_t i = 0; i < c->NumInterfaces(); ++i) {
860 Class* interface = c->GetInterface(i);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700861 f = interface->FindDeclaredStaticField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -0700862 if (f != NULL) {
863 return f;
864 }
865 }
866 }
867 return NULL;
868}
869
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700870Array* Array::Alloc(Class* array_class, int32_t component_count, size_t component_size) {
871 DCHECK_GE(component_count, 0);
872 DCHECK(array_class->IsArrayClass());
873 size_t size = SizeOf(component_count, component_size);
874 Array* array = down_cast<Array*>(Heap::AllocObject(array_class, size));
875 if (array != NULL) {
876 DCHECK(array->IsArrayInstance());
877 array->SetLength(component_count);
878 }
879 return array;
880}
881
882Array* Array::Alloc(Class* array_class, int32_t component_count) {
883 return Alloc(array_class, component_count, array_class->GetComponentSize());
884}
885
886Array* Array::AllocFromCode(uint32_t type_idx, Method* method, int32_t component_count) {
887 // TODO: throw on negative component_count
888 Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
889 if (klass == NULL) {
890 klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
891 if (klass == NULL || !klass->IsArrayClass()) {
892 UNIMPLEMENTED(FATAL) << "throw an error";
893 return NULL;
894 }
895 }
896 return Array::Alloc(klass, component_count);
897}
898
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700899template<typename T>
900PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
Elliott Hughesc1674ed2011-08-25 18:09:09 -0700901 DCHECK(array_class_ != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -0700902 Array* raw_array = Array::Alloc(array_class_, length, sizeof(T));
903 return down_cast<PrimitiveArray<T>*>(raw_array);
904}
905
906template <typename T> Class* PrimitiveArray<T>::array_class_ = NULL;
907
908// Explicitly instantiate all the primitive array types.
909template class PrimitiveArray<uint8_t>; // BooleanArray
910template class PrimitiveArray<int8_t>; // ByteArray
911template class PrimitiveArray<uint16_t>; // CharArray
912template class PrimitiveArray<double>; // DoubleArray
913template class PrimitiveArray<float>; // FloatArray
914template class PrimitiveArray<int32_t>; // IntArray
915template class PrimitiveArray<int64_t>; // LongArray
916template class PrimitiveArray<int16_t>; // ShortArray
917
Jesse Wilsonf7e85a52011-08-01 18:45:58 -0700918// TODO: get global references for these
919Class* String::java_lang_String_ = NULL;
Jesse Wilsonf7e85a52011-08-01 18:45:58 -0700920
Brian Carlstroma663ea52011-08-19 23:33:41 -0700921void String::SetClass(Class* java_lang_String) {
922 CHECK(java_lang_String_ == NULL);
923 CHECK(java_lang_String != NULL);
Jesse Wilsonf7e85a52011-08-01 18:45:58 -0700924 java_lang_String_ = java_lang_String;
Jesse Wilsonf7e85a52011-08-01 18:45:58 -0700925}
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700926
Brian Carlstroma663ea52011-08-19 23:33:41 -0700927void String::ResetClass() {
928 CHECK(java_lang_String_ != NULL);
929 java_lang_String_ = NULL;
930}
Jesse Wilsonf7e85a52011-08-01 18:45:58 -0700931
Elliott Hughescf4c6c42011-09-01 15:16:42 -0700932const String* String::Intern() const {
933 return Runtime::Current()->GetInternTable()->InternWeak(this);
934}
935
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700936int32_t String::GetHashCode() const {
937 int32_t result = GetField32(
938 OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
939 DCHECK(result != 0 ||
940 ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0);
941 return result;
942}
943
944int32_t String::GetLength() const {
945 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
946 DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
947 return result;
948}
949
950uint16_t String::CharAt(int32_t index) const {
951 // TODO: do we need this? Equals is the only caller, and could
952 // bounds check itself.
953 if (index < 0 || index >= count_) {
954 Thread* self = Thread::Current();
955 self->ThrowNewException("Ljava/lang/StringIndexOutOfBoundsException;",
956 "length=%i; index=%i", count_, index);
957 return 0;
958 }
959 return GetCharArray()->Get(index + GetOffset());
960}
961
962String* String::AllocFromUtf16(int32_t utf16_length,
963 const uint16_t* utf16_data_in,
964 int32_t hash_code) {
965 String* string = Alloc(GetJavaLangString(), utf16_length);
966 // TODO: use 16-bit wide memset variant
967 CharArray* array = const_cast<CharArray*>(string->GetCharArray());
968 for (int i = 0; i < utf16_length; i++) {
969 array->Set(i, utf16_data_in[i]);
970 }
971 if (hash_code != 0) {
972 string->SetHashCode(hash_code);
973 } else {
974 string->ComputeHashCode();
975 }
976 return string;
977}
978
979String* String::AllocFromModifiedUtf8(const char* utf) {
980 size_t char_count = CountModifiedUtf8Chars(utf);
981 return AllocFromModifiedUtf8(char_count, utf);
982}
983
984String* String::AllocFromModifiedUtf8(int32_t utf16_length,
985 const char* utf8_data_in) {
986 String* string = Alloc(GetJavaLangString(), utf16_length);
987 uint16_t* utf16_data_out =
988 const_cast<uint16_t*>(string->GetCharArray()->GetData());
989 ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
990 string->ComputeHashCode();
991 return string;
992}
993
994String* String::Alloc(Class* java_lang_String, int32_t utf16_length) {
995 return Alloc(java_lang_String, CharArray::Alloc(utf16_length));
996}
997
998String* String::Alloc(Class* java_lang_String, CharArray* array) {
999 String* string = down_cast<String*>(java_lang_String->AllocObject());
1000 string->SetArray(array);
1001 string->SetCount(array->GetLength());
1002 return string;
1003}
1004
1005bool String::Equals(const String* that) const {
1006 if (this == that) {
1007 // Quick reference equality test
1008 return true;
1009 } else if (that == NULL) {
1010 // Null isn't an instanceof anything
1011 return false;
1012 } else if (this->GetLength() != that->GetLength()) {
1013 // Quick length inequality test
1014 return false;
1015 } else {
1016 // NB don't short circuit on hash code as we're presumably here as the
1017 // hash code was already equal
1018 for (int32_t i = 0; i < that->GetLength(); ++i) {
1019 if (this->CharAt(i) != that->CharAt(i)) {
1020 return false;
1021 }
1022 }
1023 return true;
1024 }
1025}
1026
1027bool String::Equals(const uint16_t* that_chars, int32_t that_offset,
1028 int32_t that_length) const {
1029 if (this->GetLength() != that_length) {
1030 return false;
1031 } else {
1032 for (int32_t i = 0; i < that_length; ++i) {
1033 if (this->CharAt(i) != that_chars[that_offset + i]) {
1034 return false;
1035 }
1036 }
1037 return true;
1038 }
1039}
1040
1041bool String::Equals(const char* modified_utf8) const {
1042 for (int32_t i = 0; i < GetLength(); ++i) {
1043 uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
1044 if (ch == '\0' || ch != CharAt(i)) {
1045 return false;
1046 }
1047 }
1048 return *modified_utf8 == '\0';
1049}
1050
1051bool String::Equals(const StringPiece& modified_utf8) const {
1052 // TODO: do not assume C-string representation.
1053 return Equals(modified_utf8.data());
1054}
1055
1056// Create a modified UTF-8 encoded std::string from a java/lang/String object.
1057std::string String::ToModifiedUtf8() const {
1058 const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
1059 size_t byte_count(CountUtf8Bytes(chars, GetLength()));
1060 std::string result(byte_count, char(0));
1061 ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
1062 return result;
1063}
1064
Shih-wei Liao55df06b2011-08-26 14:39:27 -07001065Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
1066
1067void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {
1068 CHECK(java_lang_StackTraceElement_ == NULL);
1069 CHECK(java_lang_StackTraceElement != NULL);
1070 java_lang_StackTraceElement_ = java_lang_StackTraceElement;
1071}
1072
1073void StackTraceElement::ResetClass() {
1074 CHECK(java_lang_StackTraceElement_ != NULL);
1075 java_lang_StackTraceElement_ = NULL;
1076}
1077
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001078StackTraceElement* StackTraceElement::Alloc(const String* declaring_class,
1079 const String* method_name,
1080 const String* file_name,
1081 int32_t line_number) {
1082 StackTraceElement* trace =
1083 down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject());
1084 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_),
1085 const_cast<String*>(declaring_class), false);
1086 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_),
1087 const_cast<String*>(method_name), false);
1088 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_),
1089 const_cast<String*>(file_name), false);
1090 trace->SetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_),
1091 line_number, false);
1092 return trace;
1093}
1094
Elliott Hughes1f359b02011-07-17 14:27:17 -07001095static const char* kClassStatusNames[] = {
1096 "Error",
1097 "NotReady",
1098 "Idx",
1099 "Loaded",
1100 "Resolved",
1101 "Verifying",
1102 "Verified",
1103 "Initializing",
1104 "Initialized"
1105};
1106std::ostream& operator<<(std::ostream& os, const Class::Status& rhs) {
1107 if (rhs >= Class::kStatusError && rhs <= Class::kStatusInitialized) {
Brian Carlstromae3ac012011-07-27 01:30:28 -07001108 os << kClassStatusNames[rhs + 1];
Elliott Hughes1f359b02011-07-17 14:27:17 -07001109 } else {
Ian Rogersb033c752011-07-20 12:22:35 -07001110 os << "Class::Status[" << static_cast<int>(rhs) << "]";
Elliott Hughes1f359b02011-07-17 14:27:17 -07001111 }
1112 return os;
1113}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001114
Carl Shapiro3ee755d2011-06-28 12:11:04 -07001115} // namespace art