blob: 343f6433796638a63c923fdbf948bd93e96a2594 [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>
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07008#include <iostream>
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07009#include <string>
10#include <utility>
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070011
Elliott Hughesd8ddfd52011-08-15 14:32:53 -070012#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070013#include "class_loader.h"
Elliott Hughes54e7df12011-09-16 11:47:04 -070014#include "dex_cache.h"
15#include "dex_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070016#include "globals.h"
Brian Carlstroma40f9bc2011-07-26 21:26:07 -070017#include "heap.h"
Elliott Hughescf4c6c42011-09-01 15:16:42 -070018#include "intern_table.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070019#include "logging.h"
Elliott Hughes54e7df12011-09-16 11:47:04 -070020#include "monitor.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070021#include "runtime.h"
Elliott Hughes68e76522011-10-05 13:22:16 -070022#include "stack.h"
Carl Shapiro3ee755d2011-06-28 12:11:04 -070023
24namespace art {
25
Elliott Hughes081be7f2011-09-18 16:50:26 -070026Object* Object::Clone() {
27 Class* c = GetClass();
28 DCHECK(!c->IsClassClass());
29
30 // Object::SizeOf gets the right size even if we're an array.
31 // Using c->AllocObject() here would be wrong.
32 size_t num_bytes = SizeOf();
Brian Carlstrom40381fb2011-10-19 14:13:40 -070033 SirtRef<Object> copy(Heap::AllocObject(c, num_bytes));
34 if (copy.get() == NULL) {
Elliott Hughes081be7f2011-09-18 16:50:26 -070035 return NULL;
36 }
37
38 // Copy instance data. We assume memcpy copies by words.
39 // TODO: expose and use move32.
40 byte* src_bytes = reinterpret_cast<byte*>(this);
Brian Carlstrom40381fb2011-10-19 14:13:40 -070041 byte* dst_bytes = reinterpret_cast<byte*>(copy.get());
Elliott Hughes081be7f2011-09-18 16:50:26 -070042 size_t offset = sizeof(Object);
43 memcpy(dst_bytes + offset, src_bytes + offset, num_bytes - offset);
44
Elliott Hughes20cde902011-10-04 17:37:27 -070045 if (c->IsFinalizable()) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -070046 Heap::AddFinalizerReference(copy.get());
Elliott Hughes20cde902011-10-04 17:37:27 -070047 }
Elliott Hughes081be7f2011-09-18 16:50:26 -070048
Brian Carlstrom40381fb2011-10-19 14:13:40 -070049 return copy.get();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070050}
51
Brian Carlstrom24a3c2e2011-10-17 18:07:52 -070052uint32_t Object::GetThinLockId() {
53 return Monitor::GetThinLockId(monitor_);
Elliott Hughes5f791332011-09-15 17:45:30 -070054}
55
Elliott Hughes081be7f2011-09-18 16:50:26 -070056bool Object::IsString() const {
57 // TODO use "klass_ == String::GetJavaLangString()" instead?
58 return GetClass() == GetClass()->GetDescriptor()->GetClass();
59}
60
Elliott Hughes5f791332011-09-15 17:45:30 -070061void Object::MonitorEnter(Thread* thread) {
62 Monitor::MonitorEnter(thread, this);
63}
64
Ian Rogersff1ed472011-09-20 13:46:24 -070065bool Object::MonitorExit(Thread* thread) {
66 return Monitor::MonitorExit(thread, this);
Elliott Hughes5f791332011-09-15 17:45:30 -070067}
68
69void Object::Notify() {
70 Monitor::Notify(Thread::Current(), this);
71}
72
73void Object::NotifyAll() {
74 Monitor::NotifyAll(Thread::Current(), this);
75}
76
77void Object::Wait(int64_t ms, int32_t ns) {
78 Monitor::Wait(Thread::Current(), this, ms, ns, true);
79}
80
Ian Rogers0cfe1fb2011-08-26 03:29:44 -070081// TODO: get global references for these
82Class* Field::java_lang_reflect_Field_ = NULL;
83
84void Field::SetClass(Class* java_lang_reflect_Field) {
85 CHECK(java_lang_reflect_Field_ == NULL);
86 CHECK(java_lang_reflect_Field != NULL);
87 java_lang_reflect_Field_ = java_lang_reflect_Field;
88}
89
90void Field::ResetClass() {
91 CHECK(java_lang_reflect_Field_ != NULL);
92 java_lang_reflect_Field_ = NULL;
93}
94
95void Field::SetTypeIdx(uint32_t type_idx) {
96 SetField32(OFFSET_OF_OBJECT_MEMBER(Field, type_idx_), type_idx, false);
97}
98
99Class* Field::GetTypeDuringLinking() const {
100 // We are assured that the necessary primitive types are in the dex cache
101 // early during class linking
102 return GetDeclaringClass()->GetDexCache()->GetResolvedType(GetTypeIdx());
103}
104
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700105bool Field::IsPrimitiveType() const {
106 Class* type = GetTypeDuringLinking();
107 return (type == NULL || type->IsPrimitive());
108}
109
110Primitive::Type Field::GetPrimitiveType() const {
111 Class* type = GetTypeDuringLinking();
112 if (type == NULL) {
113 return Primitive::kPrimNot;
114 }
115 return type->GetPrimitiveType();
116}
117
118size_t Field::PrimitiveSize() const {
119 return Primitive::FieldSize(GetPrimitiveType());
120}
121
122const char* Field::GetTypeDescriptor() const {
123 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
124 const DexFile& dex_file = class_linker->FindDexFile(GetDeclaringClass()->GetDexCache());
125 const char* descriptor = dex_file.dexStringByTypeIdx(GetTypeIdx());
126 DCHECK(descriptor != NULL);
127 return descriptor;
128}
129
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700130Class* Field::GetType() const {
Elliott Hughes80609252011-09-23 17:24:51 -0700131 if (type_ == NULL) {
132 type_ = Runtime::Current()->GetClassLinker()->ResolveType(GetTypeIdx(), this);
133 }
134 return type_;
135}
136
137void Field::InitJavaFields() {
138 Thread* self = Thread::Current();
139 ScopedThreadStateChange tsc(self, Thread::kRunnable);
140 MonitorEnter(self);
141 if (type_ == NULL) {
142 InitJavaFieldsLocked();
143 }
144 MonitorExit(self);
145}
146
147void Field::InitJavaFieldsLocked() {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700148 GetType(); // Resolves type as a side-effect. May throw.
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700149}
150
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700151uint32_t Field::Get32(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700152 CHECK((object == NULL) == IsStatic()) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700153 if (IsStatic()) {
154 object = declaring_class_;
155 }
156 return object->GetField32(GetOffset(), IsVolatile());
Elliott Hughes68f4fa02011-08-21 10:46:59 -0700157}
158
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700159void Field::Set32(Object* object, uint32_t new_value) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700160 CHECK((object == NULL) == IsStatic()) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700161 if (IsStatic()) {
162 object = declaring_class_;
163 }
164 object->SetField32(GetOffset(), new_value, IsVolatile());
165}
166
167uint64_t Field::Get64(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700168 CHECK((object == NULL) == IsStatic()) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700169 if (IsStatic()) {
170 object = declaring_class_;
171 }
172 return object->GetField64(GetOffset(), IsVolatile());
173}
174
175void Field::Set64(Object* object, uint64_t new_value) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700176 CHECK((object == NULL) == IsStatic()) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700177 if (IsStatic()) {
178 object = declaring_class_;
179 }
180 object->SetField64(GetOffset(), new_value, IsVolatile());
181}
182
183Object* Field::GetObj(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700184 CHECK((object == NULL) == IsStatic()) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700185 if (IsStatic()) {
186 object = declaring_class_;
187 }
188 return object->GetFieldObject<Object*>(GetOffset(), IsVolatile());
189}
190
191void Field::SetObj(Object* object, const Object* new_value) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700192 CHECK((object == NULL) == IsStatic()) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700193 if (IsStatic()) {
194 object = declaring_class_;
195 }
196 object->SetFieldObject(GetOffset(), new_value, IsVolatile());
197}
198
199bool Field::GetBoolean(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700200 DCHECK(GetPrimitiveType() == Primitive::kPrimBoolean) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700201 return Get32(object);
202}
203
204void Field::SetBoolean(Object* object, bool z) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700205 DCHECK(GetPrimitiveType() == Primitive::kPrimBoolean) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700206 Set32(object, z);
207}
208
209int8_t Field::GetByte(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700210 DCHECK(GetPrimitiveType() == Primitive::kPrimByte) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700211 return Get32(object);
212}
213
214void Field::SetByte(Object* object, int8_t b) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700215 DCHECK(GetPrimitiveType() == Primitive::kPrimByte) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700216 Set32(object, b);
217}
218
219uint16_t Field::GetChar(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700220 DCHECK(GetPrimitiveType() == Primitive::kPrimChar) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700221 return Get32(object);
222}
223
224void Field::SetChar(Object* object, uint16_t c) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700225 DCHECK(GetPrimitiveType() == Primitive::kPrimChar) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700226 Set32(object, c);
227}
228
Ian Rogers466bb252011-10-14 03:29:56 -0700229int16_t Field::GetShort(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700230 DCHECK(GetPrimitiveType() == Primitive::kPrimShort) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700231 return Get32(object);
232}
233
Ian Rogers466bb252011-10-14 03:29:56 -0700234void Field::SetShort(Object* object, int16_t s) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700235 DCHECK(GetPrimitiveType() == Primitive::kPrimShort) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700236 Set32(object, s);
237}
238
239int32_t Field::GetInt(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700240 DCHECK(GetPrimitiveType() == Primitive::kPrimInt) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700241 return Get32(object);
242}
243
244void Field::SetInt(Object* object, int32_t i) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700245 DCHECK(GetPrimitiveType() == Primitive::kPrimInt) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700246 Set32(object, i);
247}
248
249int64_t Field::GetLong(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700250 DCHECK(GetPrimitiveType() == Primitive::kPrimLong) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700251 return Get64(object);
252}
253
254void Field::SetLong(Object* object, int64_t j) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700255 DCHECK(GetPrimitiveType() == Primitive::kPrimLong) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700256 Set64(object, j);
257}
258
259float Field::GetFloat(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700260 DCHECK(GetPrimitiveType() == Primitive::kPrimFloat) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700261 JValue float_bits;
262 float_bits.i = Get32(object);
263 return float_bits.f;
264}
265
266void Field::SetFloat(Object* object, float f) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700267 DCHECK(GetPrimitiveType() == Primitive::kPrimFloat) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700268 JValue float_bits;
269 float_bits.f = f;
270 Set32(object, float_bits.i);
271}
272
273double Field::GetDouble(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700274 DCHECK(GetPrimitiveType() == Primitive::kPrimDouble) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700275 JValue double_bits;
276 double_bits.j = Get64(object);
277 return double_bits.d;
278}
279
280void Field::SetDouble(Object* object, double d) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700281 DCHECK(GetPrimitiveType() == Primitive::kPrimDouble) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700282 JValue double_bits;
283 double_bits.d = d;
284 Set64(object, double_bits.j);
285}
286
287Object* Field::GetObject(const Object* object) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700288 CHECK(GetPrimitiveType() == Primitive::kPrimNot) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700289 return GetObj(object);
290}
291
292void Field::SetObject(Object* object, const Object* l) const {
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700293 CHECK(GetPrimitiveType() == Primitive::kPrimNot) << PrettyField(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700294 SetObj(object, l);
295}
296
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700297bool Method::IsClassInitializer() const {
298 return IsStatic() && GetName()->Equals("<clinit>");
299}
300
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700301// TODO: get global references for these
Elliott Hughes80609252011-09-23 17:24:51 -0700302Class* Method::java_lang_reflect_Constructor_ = NULL;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700303Class* Method::java_lang_reflect_Method_ = NULL;
304
Elliott Hughes80609252011-09-23 17:24:51 -0700305void Method::SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method) {
306 CHECK(java_lang_reflect_Constructor_ == NULL);
307 CHECK(java_lang_reflect_Constructor != NULL);
308 java_lang_reflect_Constructor_ = java_lang_reflect_Constructor;
309
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700310 CHECK(java_lang_reflect_Method_ == NULL);
311 CHECK(java_lang_reflect_Method != NULL);
312 java_lang_reflect_Method_ = java_lang_reflect_Method;
313}
314
Elliott Hughes80609252011-09-23 17:24:51 -0700315void Method::ResetClasses() {
316 CHECK(java_lang_reflect_Constructor_ != NULL);
317 java_lang_reflect_Constructor_ = NULL;
318
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700319 CHECK(java_lang_reflect_Method_ != NULL);
320 java_lang_reflect_Method_ = NULL;
321}
322
Elliott Hughes418d20f2011-09-22 14:00:39 -0700323Class* ExtractNextClassFromSignature(ClassLinker* class_linker, const ClassLoader* cl, const char*& p) {
324 if (*p == '[') {
325 // Something like "[[[Ljava/lang/String;".
326 const char* start = p;
327 while (*p == '[') {
328 ++p;
329 }
330 if (*p == 'L') {
331 while (*p != ';') {
332 ++p;
333 }
334 }
335 ++p; // Either the ';' or the primitive type.
336
Brian Carlstromaded5f72011-10-07 17:15:04 -0700337 std::string descriptor(start, (p - start));
Elliott Hughes418d20f2011-09-22 14:00:39 -0700338 return class_linker->FindClass(descriptor, cl);
339 } else if (*p == 'L') {
340 const char* start = p;
341 while (*p != ';') {
342 ++p;
343 }
344 ++p;
345 StringPiece descriptor(start, (p - start));
Brian Carlstromaded5f72011-10-07 17:15:04 -0700346 return class_linker->FindClass(descriptor.ToString(), cl);
Elliott Hughes418d20f2011-09-22 14:00:39 -0700347 } else {
348 return class_linker->FindPrimitiveClass(*p++);
349 }
350}
351
352void Method::InitJavaFieldsLocked() {
353 // Create the array.
354 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
355 size_t arg_count = GetShorty()->GetLength() - 1;
356 Class* array_class = class_linker->FindSystemClass("[Ljava/lang/Class;");
357 ObjectArray<Class>* parameters = ObjectArray<Class>::Alloc(array_class, arg_count);
358 if (parameters == NULL) {
359 return;
360 }
361
362 // Parse the signature, filling the array.
363 const ClassLoader* cl = GetDeclaringClass()->GetClassLoader();
364 std::string signature(GetSignature()->ToModifiedUtf8());
365 const char* p = signature.c_str();
366 DCHECK_EQ(*p, '(');
367 ++p;
368 for (size_t i = 0; i < arg_count; ++i) {
369 Class* c = ExtractNextClassFromSignature(class_linker, cl, p);
370 if (c == NULL) {
371 return;
372 }
373 parameters->Set(i, c);
374 }
375
376 DCHECK_EQ(*p, ')');
377 ++p;
378
379 java_parameter_types_ = parameters;
380 java_return_type_ = ExtractNextClassFromSignature(class_linker, cl, p);
381}
382
383void Method::InitJavaFields() {
384 Thread* self = Thread::Current();
385 ScopedThreadStateChange tsc(self, Thread::kRunnable);
386 MonitorEnter(self);
387 if (java_parameter_types_ == NULL || java_return_type_ == NULL) {
388 InitJavaFieldsLocked();
389 }
390 MonitorExit(self);
391}
392
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700393ObjectArray<String>* Method::GetDexCacheStrings() const {
394 return GetFieldObject<ObjectArray<String>*>(
395 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_strings_), false);
396}
397
398void Method::SetReturnTypeIdx(uint32_t new_return_type_idx) {
399 SetField32(OFFSET_OF_OBJECT_MEMBER(Method, java_return_type_idx_),
400 new_return_type_idx, false);
401}
402
Ian Rogers9074b992011-10-26 17:41:55 -0700403const char* Method::GetReturnTypeDescriptor() const {
404 Class* declaring_class = GetDeclaringClass();
405 DexCache* dex_cache = declaring_class->GetDexCache();
406 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
407 const DexFile& dex_file = class_linker->FindDexFile(dex_cache);
408 const char* descriptor = dex_file.dexStringByTypeIdx(GetReturnTypeIdx());
409 DCHECK(descriptor != NULL);
410 return descriptor;
411}
412
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700413Class* Method::GetReturnType() const {
Brian Carlstrom5de8fe52011-10-16 14:10:09 -0700414 DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous())
415 << PrettyMethod(this);
Jesse Wilsond81cdcc2011-10-17 14:36:48 -0400416 Class* java_return_type = java_return_type_;
417 if (java_return_type != NULL) {
418 return java_return_type;
419 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700420 // Short-cut
421 Class* result = GetDexCacheResolvedTypes()->Get(GetReturnTypeIdx());
422 if (result == NULL) {
423 // Do full linkage and set cache value for next call
424 result = Runtime::Current()->GetClassLinker()->ResolveType(GetReturnTypeIdx(), this);
425 }
Elliott Hughes14134a12011-09-30 16:55:51 -0700426 CHECK(result != NULL) << PrettyMethod(this);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700427 return result;
428}
429
430void Method::SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings) {
431 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_strings_),
432 new_dex_cache_strings, false);
433}
434
435ObjectArray<Class>* Method::GetDexCacheResolvedTypes() const {
436 return GetFieldObject<ObjectArray<Class>*>(
437 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_types_), false);
438}
439
440void Method::SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_classes) {
441 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_types_),
442 new_dex_cache_classes, false);
443}
444
445ObjectArray<Method>* Method::GetDexCacheResolvedMethods() const {
446 return GetFieldObject<ObjectArray<Method>*>(
447 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_), false);
448}
449
450void Method::SetDexCacheResolvedMethods(ObjectArray<Method>* new_dex_cache_methods) {
451 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_),
452 new_dex_cache_methods, false);
453}
454
455ObjectArray<Field>* Method::GetDexCacheResolvedFields() const {
456 return GetFieldObject<ObjectArray<Field>*>(
457 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_fields_), false);
458}
459
460void Method::SetDexCacheResolvedFields(ObjectArray<Field>* new_dex_cache_fields) {
461 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_fields_),
462 new_dex_cache_fields, false);
463}
464
465CodeAndDirectMethods* Method::GetDexCacheCodeAndDirectMethods() const {
466 return GetFieldPtr<CodeAndDirectMethods*>(
467 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_),
468 false);
469}
470
471void Method::SetDexCacheCodeAndDirectMethods(CodeAndDirectMethods* new_value) {
472 SetFieldPtr<CodeAndDirectMethods*>(
473 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_),
474 new_value, false);
475}
476
477ObjectArray<StaticStorageBase>* Method::GetDexCacheInitializedStaticStorage() const {
478 return GetFieldObject<ObjectArray<StaticStorageBase>*>(
479 OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_initialized_static_storage_),
480 false);
481}
482
483void Method::SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value) {
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700484 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_initialized_static_storage_),
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700485 new_value, false);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700486}
487
488size_t Method::NumArgRegisters(const StringPiece& shorty) {
489 CHECK_LE(1, shorty.length());
490 uint32_t num_registers = 0;
491 for (int i = 1; i < shorty.length(); ++i) {
492 char ch = shorty[i];
493 if (ch == 'D' || ch == 'J') {
494 num_registers += 2;
495 } else {
496 num_registers += 1;
Brian Carlstromb63ec392011-08-27 17:38:27 -0700497 }
498 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700499 return num_registers;
500}
501
502size_t Method::NumArgArrayBytes() const {
Brian Carlstromc74255f2011-09-11 22:47:39 -0700503 const String* shorty = GetShorty();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700504 size_t num_bytes = 0;
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700505 for (int i = 1; i < shorty->GetLength(); ++i) {
506 char ch = shorty->CharAt(i);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700507 if (ch == 'D' || ch == 'J') {
508 num_bytes += 8;
509 } else if (ch == 'L') {
510 // Argument is a reference or an array. The shorty descriptor
511 // does not distinguish between these types.
512 num_bytes += sizeof(Object*);
513 } else {
514 num_bytes += 4;
515 }
516 }
517 return num_bytes;
518}
519
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700520size_t Method::NumArgs() const {
521 // "1 +" because the first in Args is the receiver.
522 // "- 1" because we don't count the return type.
523 return (IsStatic() ? 0 : 1) + GetShorty()->GetLength() - 1;
524}
525
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700526// The number of reference arguments to this method including implicit this
527// pointer
528size_t Method::NumReferenceArgs() const {
Brian Carlstromc74255f2011-09-11 22:47:39 -0700529 const String* shorty = GetShorty();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700530 size_t result = IsStatic() ? 0 : 1; // The implicit this pointer.
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700531 for (int i = 1; i < shorty->GetLength(); i++) {
532 char ch = shorty->CharAt(i);
533 if ((ch == 'L') || (ch == '[')) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700534 result++;
535 }
536 }
537 return result;
538}
539
540// The number of long or double arguments
541size_t Method::NumLongOrDoubleArgs() const {
Brian Carlstromc74255f2011-09-11 22:47:39 -0700542 const String* shorty = GetShorty();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700543 size_t result = 0;
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700544 for (int i = 1; i < shorty->GetLength(); i++) {
545 char ch = shorty->CharAt(i);
546 if ((ch == 'D') || (ch == 'J')) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700547 result++;
548 }
549 }
550 return result;
551}
552
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700553// Is the given method parameter a reference?
554bool Method::IsParamAReference(unsigned int param) const {
555 CHECK_LT(param, NumArgs());
556 if (IsStatic()) {
557 param++; // 0th argument must skip return value at start of the shorty
558 } else if (param == 0) {
559 return true; // this argument
560 }
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700561 return GetShorty()->CharAt(param) == 'L';
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700562}
563
564// Is the given method parameter a long or double?
565bool Method::IsParamALongOrDouble(unsigned int param) const {
566 CHECK_LT(param, NumArgs());
567 if (IsStatic()) {
568 param++; // 0th argument must skip return value at start of the shorty
569 } else if (param == 0) {
570 return false; // this argument
571 }
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700572 char ch = GetShorty()->CharAt(param);
573 return (ch == 'J' || ch == 'D');
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700574}
575
576static size_t ShortyCharToSize(char x) {
577 switch (x) {
578 case 'V': return 0;
579 case '[': return kPointerSize;
580 case 'L': return kPointerSize;
581 case 'D': return 8;
582 case 'J': return 8;
583 default: return 4;
584 }
585}
586
587size_t Method::ParamSize(unsigned int param) const {
588 CHECK_LT(param, NumArgs());
589 if (IsStatic()) {
590 param++; // 0th argument must skip return value at start of the shorty
591 } else if (param == 0) {
592 return kPointerSize; // this argument
593 }
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700594 return ShortyCharToSize(GetShorty()->CharAt(param));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700595}
596
597size_t Method::ReturnSize() const {
Brian Carlstrom2ed67392011-09-09 14:53:28 -0700598 return ShortyCharToSize(GetShorty()->CharAt(0));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700599}
600
Ian Rogers466bb252011-10-14 03:29:56 -0700601Method* Method::FindOverriddenMethod() const {
602 if (IsStatic()) {
603 return NULL;
604 }
605 Class* declaring_class = GetDeclaringClass();
606 Class* super_class = declaring_class->GetSuperClass();
607 uint16_t method_index = GetMethodIndex();
608 ObjectArray<Method>* super_class_vtable = super_class->GetVTable();
609 Method* result = NULL;
610 if (super_class_vtable != NULL && method_index < super_class_vtable->GetLength()) {
611 result = super_class_vtable->Get(method_index);
612 } else {
613 ObjectArray<Class>* interfaces = declaring_class->GetInterfaces();
614 String* name = GetName();
615 String* signature = GetSignature();
616 for (int32_t i = 0; i < interfaces->GetLength() && result == NULL; i++) {
617 Class* interface = interfaces->Get(i);
618 result = interface->FindInterfaceMethod(name, signature);
619 }
620 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700621 DCHECK(result == NULL || HasSameNameAndSignature(result));
Ian Rogers466bb252011-10-14 03:29:56 -0700622 return result;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700623}
624
Ian Rogersbdb03912011-09-14 00:55:44 -0700625uint32_t Method::ToDexPC(const uintptr_t pc) const {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700626 const uint32_t* mapping_table = GetMappingTable();
Ian Rogersbdb03912011-09-14 00:55:44 -0700627 if (mapping_table == NULL) {
Brian Carlstrom26c935a2011-10-16 14:52:35 -0700628 DCHECK(IsNative() || IsCalleeSaveMethod()) << PrettyMethod(this);
Ian Rogers67375ac2011-09-14 00:55:44 -0700629 return DexFile::kDexNoIndex; // Special no mapping case
Ian Rogersbdb03912011-09-14 00:55:44 -0700630 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700631 size_t mapping_table_length = GetMappingTableLength();
Ian Rogersbdb03912011-09-14 00:55:44 -0700632 uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(GetCode());
Ian Rogersbdb03912011-09-14 00:55:44 -0700633 uint32_t best_offset = 0;
634 uint32_t best_dex_offset = 0;
635 for (size_t i = 0; i < mapping_table_length; i += 2) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700636 uint32_t map_offset = mapping_table[i];
637 uint32_t map_dex_offset = mapping_table[i + 1];
Ian Rogersbdb03912011-09-14 00:55:44 -0700638 if (map_offset == sought_offset) {
639 best_offset = map_offset;
640 best_dex_offset = map_dex_offset;
641 break;
642 }
643 if (map_offset < sought_offset && map_offset > best_offset) {
644 best_offset = map_offset;
645 best_dex_offset = map_dex_offset;
646 }
647 }
648 return best_dex_offset;
649}
650
651uintptr_t Method::ToNativePC(const uint32_t dex_pc) const {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700652 const uint32_t* mapping_table = GetMappingTable();
Ian Rogersbdb03912011-09-14 00:55:44 -0700653 if (mapping_table == NULL) {
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700654 DCHECK_EQ(dex_pc, 0U);
Ian Rogersbdb03912011-09-14 00:55:44 -0700655 return 0; // Special no mapping/pc == 0 case
656 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700657 size_t mapping_table_length = GetMappingTableLength();
Ian Rogersbdb03912011-09-14 00:55:44 -0700658 for (size_t i = 0; i < mapping_table_length; i += 2) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700659 uint32_t map_offset = mapping_table[i];
660 uint32_t map_dex_offset = mapping_table[i + 1];
Ian Rogersbdb03912011-09-14 00:55:44 -0700661 if (map_dex_offset == dex_pc) {
Ian Rogersbdb03912011-09-14 00:55:44 -0700662 return reinterpret_cast<uintptr_t>(GetCode()) + map_offset;
663 }
664 }
665 LOG(FATAL) << "Looking up Dex PC not contained in method";
666 return 0;
667}
668
669uint32_t Method::FindCatchBlock(Class* exception_type, uint32_t dex_pc) const {
670 DexCache* dex_cache = GetDeclaringClass()->GetDexCache();
671 const ClassLoader* class_loader = GetDeclaringClass()->GetClassLoader();
672 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
673 const DexFile& dex_file = class_linker->FindDexFile(dex_cache);
674 const DexFile::CodeItem* code_item = dex_file.GetCodeItem(GetCodeItemOffset());
675 // Iterate over the catch handlers associated with dex_pc
676 for (DexFile::CatchHandlerIterator iter = dex_file.dexFindCatchHandler(*code_item, dex_pc);
677 !iter.HasNext(); iter.Next()) {
678 uint32_t iter_type_idx = iter.Get().type_idx_;
679 // Catch all case
Elliott Hughes80609252011-09-23 17:24:51 -0700680 if (iter_type_idx == DexFile::kDexNoIndex) {
Ian Rogersbdb03912011-09-14 00:55:44 -0700681 return iter.Get().address_;
682 }
683 // Does this catch exception type apply?
684 Class* iter_exception_type =
685 class_linker->ResolveType(dex_file, iter_type_idx, dex_cache, class_loader);
686 if (iter_exception_type->IsAssignableFrom(exception_type)) {
687 return iter.Get().address_;
688 }
689 }
690 // Handler not found
691 return DexFile::kDexNoIndex;
692}
693
Elliott Hughesf5ecf062011-09-06 17:37:59 -0700694void Method::Invoke(Thread* self, Object* receiver, byte* args, JValue* result) const {
695 // Push a transition back into managed code onto the linked list in thread.
696 CHECK_EQ(Thread::kRunnable, self->GetState());
697 NativeToManagedRecord record;
698 self->PushNativeToManagedRecord(&record);
699
700 // Call the invoke stub associated with the method.
701 // Pass everything as arguments.
702 const Method::InvokeStub* stub = GetInvokeStub();
Elliott Hughes1240dad2011-09-09 16:24:50 -0700703
704 bool have_executable_code = (GetCode() != NULL);
705#if !defined(__arm__)
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700706 // Currently we can only compile non-native methods for ARM.
707 have_executable_code = IsNative();
Elliott Hughes1240dad2011-09-09 16:24:50 -0700708#endif
709
710 if (have_executable_code && stub != NULL) {
Elliott Hughes9f865372011-10-11 15:04:19 -0700711 bool log = false;
712 if (log) {
713 LOG(INFO) << "invoking " << PrettyMethod(this) << " code=" << (void*) GetCode() << " stub=" << (void*) stub;
714 }
Elliott Hughesf5ecf062011-09-06 17:37:59 -0700715 (*stub)(this, receiver, self, args, result);
Elliott Hughes9f865372011-10-11 15:04:19 -0700716 if (log) {
717 LOG(INFO) << "returned " << PrettyMethod(this) << " code=" << (void*) GetCode() << " stub=" << (void*) stub;
718 }
Elliott Hughesf5ecf062011-09-06 17:37:59 -0700719 } else {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700720 if (Runtime::Current()->IsStarted()) {
721 LOG(WARNING) << "Not invoking method with no associated code: " << PrettyMethod(this);
722 }
Elliott Hughesf5ecf062011-09-06 17:37:59 -0700723 if (result != NULL) {
724 result->j = 0;
725 }
726 }
727
728 // Pop transition.
729 self->PopNativeToManagedRecord(record);
730}
731
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700732bool Method::IsRegistered() const {
Brian Carlstrom16192862011-09-12 17:50:06 -0700733 void* native_method = GetFieldPtr<void*>(OFFSET_OF_OBJECT_MEMBER(Method, native_method_), false);
734 void* jni_stub = Runtime::Current()->GetJniStubArray()->GetData();
735 return native_method != jni_stub;
736}
737
738void Method::RegisterNative(const void* native_method) {
Brian Carlstrom5de8fe52011-10-16 14:10:09 -0700739 CHECK(IsNative()) << PrettyMethod(this);
740 CHECK(native_method != NULL) << PrettyMethod(this);
Brian Carlstrom16192862011-09-12 17:50:06 -0700741 SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(Method, native_method_),
742 native_method, false);
743}
744
745void Method::UnregisterNative() {
Brian Carlstrom5de8fe52011-10-16 14:10:09 -0700746 CHECK(IsNative()) << PrettyMethod(this);
Brian Carlstrom16192862011-09-12 17:50:06 -0700747 // restore stub to lookup native pointer via dlsym
748 RegisterNative(Runtime::Current()->GetJniStubArray()->GetData());
749}
750
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700751void Class::SetStatus(Status new_status) {
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700752 CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted())
753 << PrettyClass(this) << " " << GetStatus() << " -> " << new_status;
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700754 CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700755 return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700756}
757
758DexCache* Class::GetDexCache() const {
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700759 return GetFieldObject<DexCache*>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700760}
761
762void Class::SetDexCache(DexCache* new_dex_cache) {
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700763 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700764}
765
Brian Carlstrom1f870082011-08-23 16:02:11 -0700766Object* Class::AllocObject() {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700767 DCHECK(!IsAbstract()) << PrettyClass(this);
768 DCHECK(!IsInterface()) << PrettyClass(this);
769 DCHECK(!IsPrimitive()) << PrettyClass(this);
Brian Carlstrom96a253a2011-10-27 18:38:10 -0700770 DCHECK(!IsArrayClass()) << PrettyClass(this);
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700771 DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
Brian Carlstrom96a253a2011-10-27 18:38:10 -0700772 DCHECK_GE(this->object_size_, sizeof(Object));
Brian Carlstrom1f870082011-08-23 16:02:11 -0700773 return Heap::AllocObject(this, this->object_size_);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700774}
775
Elliott Hughes4681c802011-09-25 18:04:37 -0700776void Class::DumpClass(std::ostream& os, int flags) const {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700777 if ((flags & kDumpClassFullDetail) == 0) {
778 os << PrettyClass(this);
779 if ((flags & kDumpClassClassLoader) != 0) {
780 os << ' ' << GetClassLoader();
781 }
782 if ((flags & kDumpClassInitialized) != 0) {
783 os << ' ' << GetStatus();
784 }
785 os << std::endl;
786 return;
787 }
788
789 Class* super = GetSuperClass();
790 os << "----- " << (IsInterface() ? "interface" : "class") << " "
791 << "'" << GetDescriptor()->ToModifiedUtf8() << "' cl=" << GetClassLoader() << " -----\n",
792 os << " objectSize=" << SizeOf() << " "
793 << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n",
794 os << StringPrintf(" access=0x%04x.%04x\n",
795 GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
796 if (super != NULL) {
797 os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n";
798 }
799 if (IsArrayClass()) {
800 os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
801 }
802 if (NumInterfaces() > 0) {
803 os << " interfaces (" << NumInterfaces() << "):\n";
804 for (size_t i = 0; i < NumInterfaces(); ++i) {
805 Class* interface = GetInterface(i);
806 const ClassLoader* cl = interface->GetClassLoader();
807 os << StringPrintf(" %2d: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
808 }
809 }
810 os << " vtable (" << NumVirtualMethods() << " entries, "
811 << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n";
812 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
Elliott Hughes4681c802011-09-25 18:04:37 -0700813 os << StringPrintf(" %2d: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str());
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700814 }
815 os << " direct methods (" << NumDirectMethods() << " entries):\n";
816 for (size_t i = 0; i < NumDirectMethods(); ++i) {
817 os << StringPrintf(" %2d: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str());
818 }
819 if (NumStaticFields() > 0) {
820 os << " static fields (" << NumStaticFields() << " entries):\n";
Elliott Hughes03f03492011-09-26 13:38:08 -0700821 if (IsResolved() || IsErroneous()) {
Elliott Hughes4681c802011-09-25 18:04:37 -0700822 for (size_t i = 0; i < NumStaticFields(); ++i) {
Elliott Hughes03f03492011-09-26 13:38:08 -0700823 os << StringPrintf(" %2d: %s\n", i, PrettyField(GetStaticField(i)).c_str());
Elliott Hughes4681c802011-09-25 18:04:37 -0700824 }
825 } else {
826 os << " <not yet available>";
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700827 }
828 }
829 if (NumInstanceFields() > 0) {
830 os << " instance fields (" << NumInstanceFields() << " entries):\n";
Elliott Hughes03f03492011-09-26 13:38:08 -0700831 if (IsResolved() || IsErroneous()) {
Elliott Hughes4681c802011-09-25 18:04:37 -0700832 for (size_t i = 0; i < NumInstanceFields(); ++i) {
Elliott Hughes03f03492011-09-26 13:38:08 -0700833 os << StringPrintf(" %2d: %s\n", i, PrettyField(GetInstanceField(i)).c_str());
Elliott Hughes4681c802011-09-25 18:04:37 -0700834 }
835 } else {
836 os << " <not yet available>";
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700837 }
838 }
839}
840
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700841void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
842 if (new_reference_offsets != CLASS_WALK_SUPER) {
843 // Sanity check that the number of bits set in the reference offset bitmap
844 // agrees with the number of references
845 Class* cur = this;
846 size_t cnt = 0;
847 while (cur) {
848 cnt += cur->NumReferenceInstanceFieldsDuringLinking();
849 cur = cur->GetSuperClass();
850 }
851 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), cnt);
852 }
853 SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
854 new_reference_offsets, false);
855}
856
857void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
858 if (new_reference_offsets != CLASS_WALK_SUPER) {
859 // Sanity check that the number of bits set in the reference offset bitmap
860 // agrees with the number of references
861 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets),
862 NumReferenceStaticFieldsDuringLinking());
863 }
864 SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
865 new_reference_offsets, false);
866}
867
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700868bool Class::Implements(const Class* klass) const {
869 DCHECK(klass != NULL);
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700870 DCHECK(klass->IsInterface()) << PrettyClass(this);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700871 // All interfaces implemented directly and by our superclass, and
872 // recursively all super-interfaces of those interfaces, are listed
873 // in iftable_, so we can just do a linear scan through that.
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700874 int32_t iftable_count = GetIfTableCount();
875 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
876 for (int32_t i = 0; i < iftable_count; i++) {
877 if (iftable->Get(i)->GetInterface() == klass) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700878 return true;
879 }
880 }
881 return false;
882}
883
884// Determine whether "this" is assignable from "klazz", where both of these
885// are array classes.
886//
887// Consider an array class, e.g. Y[][], where Y is a subclass of X.
888// Y[][] = Y[][] --> true (identity)
889// X[][] = Y[][] --> true (element superclass)
890// Y = Y[][] --> false
891// Y[] = Y[][] --> false
892// Object = Y[][] --> true (everything is an object)
893// Object[] = Y[][] --> true
894// Object[][] = Y[][] --> true
895// Object[][][] = Y[][] --> false (too many []s)
896// Serializable = Y[][] --> true (all arrays are Serializable)
897// Serializable[] = Y[][] --> true
898// Serializable[][] = Y[][] --> false (unless Y is Serializable)
899//
900// Don't forget about primitive types.
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700901// Object[] = int[] --> false
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700902//
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700903bool Class::IsArrayAssignableFromArray(const Class* src) const {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700904 DCHECK(IsArrayClass()) << PrettyClass(this);
905 DCHECK(src->IsArrayClass()) << PrettyClass(src);
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700906 return GetComponentType()->IsAssignableFrom(src->GetComponentType());
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700907}
908
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700909bool Class::IsAssignableFromArray(const Class* src) const {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700910 DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
911 DCHECK(src->IsArrayClass()) << PrettyClass(src);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700912 if (!IsArrayClass()) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700913 // If "this" is not also an array, it must be Object.
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700914 // src's super should be java_lang_Object, since it is an array.
915 Class* java_lang_Object = src->GetSuperClass();
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700916 DCHECK(java_lang_Object != NULL) << PrettyClass(src);
917 DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700918 return this == java_lang_Object;
919 }
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700920 return IsArrayAssignableFromArray(src);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700921}
922
923bool Class::IsSubClass(const Class* klass) const {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700924 DCHECK(!IsInterface()) << PrettyClass(this);
925 DCHECK(!IsArrayClass()) << PrettyClass(this);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700926 const Class* current = this;
927 do {
928 if (current == klass) {
929 return true;
930 }
931 current = current->GetSuperClass();
932 } while (current != NULL);
933 return false;
934}
935
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700936bool Class::IsInSamePackage(const String* descriptor_string_1,
937 const String* descriptor_string_2) {
938 const std::string descriptor1(descriptor_string_1->ToModifiedUtf8());
939 const std::string descriptor2(descriptor_string_2->ToModifiedUtf8());
940
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700941 size_t i = 0;
942 while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
943 ++i;
944 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700945 if (descriptor1.find('/', i) != StringPiece::npos ||
946 descriptor2.find('/', i) != StringPiece::npos) {
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700947 return false;
948 } else {
949 return true;
950 }
951}
952
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700953#if 0
Ian Rogersb033c752011-07-20 12:22:35 -0700954bool Class::IsInSamePackage(const StringPiece& descriptor1,
955 const StringPiece& descriptor2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700956 size_t size = std::min(descriptor1.size(), descriptor2.size());
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700957 std::pair<StringPiece::const_iterator, StringPiece::const_iterator> pos;
Ian Rogersb033c752011-07-20 12:22:35 -0700958 pos = std::mismatch(descriptor1.begin(), descriptor1.begin() + size,
959 descriptor2.begin());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700960 return !(*(pos.second).rfind('/') != npos && descriptor2.rfind('/') != npos);
961}
962#endif
963
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700964bool Class::IsInSamePackage(const Class* that) const {
965 const Class* klass1 = this;
966 const Class* klass2 = that;
967 if (klass1 == klass2) {
968 return true;
969 }
970 // Class loaders must match.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700971 if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700972 return false;
973 }
974 // Arrays are in the same package when their element classes are.
jeffhao4a801a42011-09-23 13:53:40 -0700975 while (klass1->IsArrayClass()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700976 klass1 = klass1->GetComponentType();
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700977 }
jeffhao4a801a42011-09-23 13:53:40 -0700978 while (klass2->IsArrayClass()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700979 klass2 = klass2->GetComponentType();
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700980 }
981 // Compare the package part of the descriptor string.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700982 return IsInSamePackage(klass1->descriptor_, klass2->descriptor_);
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700983}
984
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700985const ClassLoader* Class::GetClassLoader() const {
Ian Rogersd81871c2011-10-03 13:57:23 -0700986 return GetFieldObject<const ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
Brian Carlstromb9edb842011-08-28 16:31:06 -0700987}
988
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700989void Class::SetClassLoader(const ClassLoader* new_cl) {
990 ClassLoader* new_class_loader = const_cast<ClassLoader*>(new_cl);
Ian Rogersd81871c2011-10-03 13:57:23 -0700991 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700992}
993
Ian Rogersb04f69f2011-10-17 00:40:54 -0700994Method* Class::FindVirtualMethodForInterface(Method* method, bool can_throw) {
Brian Carlstrom30b94452011-08-25 21:35:26 -0700995 Class* declaring_class = method->GetDeclaringClass();
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700996 DCHECK(declaring_class != NULL) << PrettyClass(this);
997 DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
Brian Carlstrom30b94452011-08-25 21:35:26 -0700998 // TODO cache to improve lookup speed
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700999 int32_t iftable_count = GetIfTableCount();
1000 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
1001 for (int32_t i = 0; i < iftable_count; i++) {
1002 InterfaceEntry* interface_entry = iftable->Get(i);
1003 if (interface_entry->GetInterface() == declaring_class) {
1004 return interface_entry->GetMethodArray()->Get(method->GetMethodIndex());
Brian Carlstrom30b94452011-08-25 21:35:26 -07001005 }
1006 }
Ian Rogersb04f69f2011-10-17 00:40:54 -07001007 if (can_throw) {
1008 Thread::Current()->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
1009 "Class %s does not implement interface %s",
1010 PrettyDescriptor(GetDescriptor()).c_str(),
1011 PrettyDescriptor(declaring_class->GetDescriptor()).c_str());
1012 }
Brian Carlstrom30b94452011-08-25 21:35:26 -07001013 return NULL;
1014}
1015
Ian Rogers466bb252011-10-14 03:29:56 -07001016Method* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const {
jeffhaobdb76512011-09-07 11:43:16 -07001017 // Check the current class before checking the interfaces.
1018 Method* method = FindVirtualMethod(name, signature);
1019 if (method != NULL) {
1020 return method;
1021 }
1022
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001023 int32_t iftable_count = GetIfTableCount();
1024 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
1025 for (int32_t i = 0; i < iftable_count; i++) {
1026 method = iftable->Get(i)->GetInterface()->FindVirtualMethod(name, signature);
jeffhaobdb76512011-09-07 11:43:16 -07001027 if (method != NULL) {
1028 return method;
1029 }
1030 }
1031 return NULL;
1032}
1033
Ian Rogers466bb252011-10-14 03:29:56 -07001034Method* Class::FindInterfaceMethod(String* name, String* signature) const {
1035 // Check the current class before checking the interfaces.
1036 Method* method = FindVirtualMethod(name, signature);
1037 if (method != NULL) {
1038 return method;
1039 }
1040 int32_t iftable_count = GetIfTableCount();
1041 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
1042 for (int32_t i = 0; i < iftable_count; i++) {
1043 Class* interface = iftable->Get(i)->GetInterface();
1044 method = interface->FindVirtualMethod(name, signature);
1045 if (method != NULL) {
1046 return method;
1047 }
1048 }
1049 return NULL;
1050}
1051
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001052Method* Class::FindDeclaredDirectMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001053 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001054 for (size_t i = 0; i < NumDirectMethods(); ++i) {
Ian Rogersb033c752011-07-20 12:22:35 -07001055 Method* method = GetDirectMethod(i);
Carl Shapiro8860c0e2011-08-04 17:36:16 -07001056 if (method->GetName()->Equals(name) &&
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001057 method->GetSignature()->Equals(signature)) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001058 return method;
Ian Rogersb033c752011-07-20 12:22:35 -07001059 }
1060 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001061 return NULL;
Ian Rogersb033c752011-07-20 12:22:35 -07001062}
1063
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001064Method* Class::FindDirectMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001065 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001066 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001067 Method* method = klass->FindDeclaredDirectMethod(name, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001068 if (method != NULL) {
1069 return method;
1070 }
1071 }
1072 return NULL;
1073}
1074
1075Method* Class::FindDeclaredVirtualMethod(const StringPiece& name,
Ian Rogers466bb252011-10-14 03:29:56 -07001076 const StringPiece& signature) const {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001077 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
Ian Rogersb033c752011-07-20 12:22:35 -07001078 Method* method = GetVirtualMethod(i);
Ian Rogers466bb252011-10-14 03:29:56 -07001079 if (method->GetName()->Equals(name) && method->GetSignature()->Equals(signature)) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001080 return method;
Ian Rogersb033c752011-07-20 12:22:35 -07001081 }
1082 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001083 return NULL;
Ian Rogersb033c752011-07-20 12:22:35 -07001084}
1085
Ian Rogers466bb252011-10-14 03:29:56 -07001086Method* Class::FindDeclaredVirtualMethod(String* name, String* signature) const {
1087 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
1088 Method* method = GetVirtualMethod(i);
1089 if (method->GetName() == name && method->GetSignature() == signature) {
1090 return method;
Ian Rogers466bb252011-10-14 03:29:56 -07001091 }
1092 }
1093 return NULL;
1094}
1095
1096Method* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
1097 for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
1098 Method* method = klass->FindDeclaredVirtualMethod(name, signature);
1099 if (method != NULL) {
1100 return method;
1101 }
1102 }
1103 return NULL;
1104}
1105
1106Method* Class::FindVirtualMethod(String* name, String* signature) const {
1107 for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
Elliott Hughescc5f9a92011-09-28 19:17:29 -07001108 Method* method = klass->FindDeclaredVirtualMethod(name, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001109 if (method != NULL) {
1110 return method;
1111 }
1112 }
1113 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001114}
1115
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001116Field* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001117 // Is the field in this class?
1118 // Interfaces are not relevant because they can't contain instance fields.
1119 for (size_t i = 0; i < NumInstanceFields(); ++i) {
1120 Field* f = GetInstanceField(i);
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001121 if (f->GetName()->Equals(name) &&
1122 StringPiece(f->GetTypeDescriptor()) == type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001123 return f;
1124 }
1125 }
1126 return NULL;
1127}
1128
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001129Field* Class::FindDeclaredInstanceField(String* name, String* type) {
1130 // Is the field in this class?
1131 // Interfaces are not relevant because they can't contain instance fields.
1132 for (size_t i = 0; i < NumInstanceFields(); ++i) {
1133 Field* f = GetInstanceField(i);
1134 if (f->GetName() == name && type->Equals(f->GetTypeDescriptor())) {
1135 return f;
1136 }
1137 }
1138 return NULL;
1139}
1140
1141Field* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001142 // Is the field in this class, or any of its superclasses?
1143 // Interfaces are not relevant because they can't contain instance fields.
1144 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001145 Field* f = c->FindDeclaredInstanceField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -07001146 if (f != NULL) {
1147 return f;
1148 }
1149 }
1150 return NULL;
1151}
1152
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001153Field* Class::FindInstanceField(String* name, String* type) {
1154 // Is the field in this class, or any of its superclasses?
1155 // Interfaces are not relevant because they can't contain instance fields.
1156 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
1157 Field* f = c->FindDeclaredInstanceField(name, type);
1158 if (f != NULL) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001159 return f;
1160 }
1161 }
1162 return NULL;
1163}
1164
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001165Field* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
1166 DCHECK(type != NULL);
1167 for (size_t i = 0; i < NumStaticFields(); ++i) {
1168 Field* f = GetStaticField(i);
1169 if (f->GetName()->Equals(name) && StringPiece(f->GetTypeDescriptor()) == type) {
1170 return f;
1171 }
1172 }
1173 return NULL;
1174}
1175
1176Field* Class::FindDeclaredStaticField(String* name, String* type) {
1177 DCHECK(type != NULL);
1178 for (size_t i = 0; i < NumStaticFields(); ++i) {
1179 Field* f = GetStaticField(i);
1180 if (f->GetName() == name && type->Equals(f->GetTypeDescriptor())) {
1181 return f;
1182 }
1183 }
1184 return NULL;
1185}
1186
1187Field* Class::FindStaticField(const StringPiece& name, const StringPiece& type) {
1188 // Is the field in this class (or its interfaces), or any of its
1189 // superclasses (or their interfaces)?
1190 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
1191 // Is the field in this class?
1192 Field* f = c->FindDeclaredStaticField(name, type);
1193 if (f != NULL) {
1194 return f;
1195 }
1196
1197 // Is this field in any of this class' interfaces?
1198 for (int32_t i = 0; i < c->GetIfTableCount(); ++i) {
1199 InterfaceEntry* interface_entry = c->GetIfTable()->Get(i);
1200 Class* interface = interface_entry->GetInterface();
1201 f = interface->FindDeclaredStaticField(name, type);
1202 if (f != NULL) {
1203 return f;
1204 }
1205 }
1206 }
1207 return NULL;
1208}
1209
1210Field* Class::FindStaticField(String* name, String* type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001211 // Is the field in this class (or its interfaces), or any of its
1212 // superclasses (or their interfaces)?
1213 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
1214 // Is the field in this class?
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001215 Field* f = c->FindDeclaredStaticField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -07001216 if (f != NULL) {
1217 return f;
1218 }
1219
1220 // Is this field in any of this class' interfaces?
jeffhaoe0cfb6f2011-09-22 16:42:56 -07001221 for (int32_t i = 0; i < c->GetIfTableCount(); ++i) {
1222 InterfaceEntry* interface_entry = c->GetIfTable()->Get(i);
1223 Class* interface = interface_entry->GetInterface();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001224 f = interface->FindDeclaredStaticField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -07001225 if (f != NULL) {
1226 return f;
1227 }
1228 }
1229 }
1230 return NULL;
1231}
1232
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001233Array* Array::Alloc(Class* array_class, int32_t component_count, size_t component_size) {
Elliott Hughes0f4c41d2011-09-04 14:58:03 -07001234 DCHECK(array_class != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001235 DCHECK_GE(component_count, 0);
1236 DCHECK(array_class->IsArrayClass());
Elliott Hughesb408de72011-10-04 14:35:05 -07001237
1238 size_t header_size = sizeof(Array);
1239 size_t data_size = component_count * component_size;
1240 size_t size = header_size + data_size;
1241
1242 // Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
1243 size_t component_shift = sizeof(size_t) * 8 - 1 - CLZ(component_size);
1244 if (data_size >> component_shift != size_t(component_count) || size < data_size) {
1245 Thread::Current()->ThrowNewExceptionF("Ljava/lang/OutOfMemoryError;",
1246 "%s of length %zd exceeds the VM limit",
1247 PrettyDescriptor(array_class->GetDescriptor()).c_str(), component_count);
1248 return NULL;
1249 }
1250
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001251 Array* array = down_cast<Array*>(Heap::AllocObject(array_class, size));
1252 if (array != NULL) {
1253 DCHECK(array->IsArrayInstance());
1254 array->SetLength(component_count);
1255 }
1256 return array;
1257}
1258
1259Array* Array::Alloc(Class* array_class, int32_t component_count) {
1260 return Alloc(array_class, component_count, array_class->GetComponentSize());
1261}
1262
Elliott Hughes80609252011-09-23 17:24:51 -07001263bool Array::ThrowArrayIndexOutOfBoundsException(int32_t index) const {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001264 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Elliott Hughes80609252011-09-23 17:24:51 -07001265 "length=%i; index=%i", length_, index);
1266 return false;
1267}
1268
1269bool Array::ThrowArrayStoreException(Object* object) const {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001270 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
Elliott Hughes80609252011-09-23 17:24:51 -07001271 "Can't store an element of type %s into an array of type %s",
1272 PrettyTypeOf(object).c_str(), PrettyTypeOf(this).c_str());
1273 return false;
1274}
1275
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001276template<typename T>
1277PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
Elliott Hughesc1674ed2011-08-25 18:09:09 -07001278 DCHECK(array_class_ != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001279 Array* raw_array = Array::Alloc(array_class_, length, sizeof(T));
1280 return down_cast<PrimitiveArray<T>*>(raw_array);
1281}
1282
1283template <typename T> Class* PrimitiveArray<T>::array_class_ = NULL;
1284
1285// Explicitly instantiate all the primitive array types.
1286template class PrimitiveArray<uint8_t>; // BooleanArray
1287template class PrimitiveArray<int8_t>; // ByteArray
1288template class PrimitiveArray<uint16_t>; // CharArray
1289template class PrimitiveArray<double>; // DoubleArray
1290template class PrimitiveArray<float>; // FloatArray
1291template class PrimitiveArray<int32_t>; // IntArray
1292template class PrimitiveArray<int64_t>; // LongArray
1293template class PrimitiveArray<int16_t>; // ShortArray
1294
Ian Rogers466bb252011-10-14 03:29:56 -07001295// Explicitly instantiate Class[][]
1296template class ObjectArray<ObjectArray<Class> >;
1297
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001298// TODO: get global references for these
1299Class* String::java_lang_String_ = NULL;
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001300
Brian Carlstroma663ea52011-08-19 23:33:41 -07001301void String::SetClass(Class* java_lang_String) {
1302 CHECK(java_lang_String_ == NULL);
1303 CHECK(java_lang_String != NULL);
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001304 java_lang_String_ = java_lang_String;
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001305}
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001306
Brian Carlstroma663ea52011-08-19 23:33:41 -07001307void String::ResetClass() {
1308 CHECK(java_lang_String_ != NULL);
1309 java_lang_String_ = NULL;
1310}
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001311
Brian Carlstromc74255f2011-09-11 22:47:39 -07001312String* String::Intern() {
Elliott Hughescf4c6c42011-09-01 15:16:42 -07001313 return Runtime::Current()->GetInternTable()->InternWeak(this);
1314}
1315
Brian Carlstrom395520e2011-09-25 19:35:00 -07001316int32_t String::GetHashCode() {
1317 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
1318 if (result == 0) {
1319 ComputeHashCode();
1320 }
1321 result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
1322 DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
1323 << ToModifiedUtf8() << " " << result;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001324 return result;
1325}
1326
1327int32_t String::GetLength() const {
1328 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
1329 DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
1330 return result;
1331}
1332
1333uint16_t String::CharAt(int32_t index) const {
1334 // TODO: do we need this? Equals is the only caller, and could
1335 // bounds check itself.
1336 if (index < 0 || index >= count_) {
1337 Thread* self = Thread::Current();
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001338 self->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001339 "length=%i; index=%i", count_, index);
1340 return 0;
1341 }
1342 return GetCharArray()->Get(index + GetOffset());
1343}
1344
1345String* String::AllocFromUtf16(int32_t utf16_length,
1346 const uint16_t* utf16_data_in,
1347 int32_t hash_code) {
1348 String* string = Alloc(GetJavaLangString(), utf16_length);
Elliott Hughesb51036c2011-10-12 23:49:11 -07001349 if (string == NULL) {
1350 return NULL;
1351 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001352 // TODO: use 16-bit wide memset variant
1353 CharArray* array = const_cast<CharArray*>(string->GetCharArray());
Elliott Hughesb51036c2011-10-12 23:49:11 -07001354 if (array == NULL) {
1355 return NULL;
1356 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001357 for (int i = 0; i < utf16_length; i++) {
1358 array->Set(i, utf16_data_in[i]);
1359 }
1360 if (hash_code != 0) {
1361 string->SetHashCode(hash_code);
1362 } else {
1363 string->ComputeHashCode();
1364 }
1365 return string;
1366}
1367
1368String* String::AllocFromModifiedUtf8(const char* utf) {
1369 size_t char_count = CountModifiedUtf8Chars(utf);
1370 return AllocFromModifiedUtf8(char_count, utf);
1371}
1372
1373String* String::AllocFromModifiedUtf8(int32_t utf16_length,
1374 const char* utf8_data_in) {
1375 String* string = Alloc(GetJavaLangString(), utf16_length);
Elliott Hughesb51036c2011-10-12 23:49:11 -07001376 if (string == NULL) {
1377 return NULL;
1378 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001379 uint16_t* utf16_data_out =
1380 const_cast<uint16_t*>(string->GetCharArray()->GetData());
1381 ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
1382 string->ComputeHashCode();
1383 return string;
1384}
1385
1386String* String::Alloc(Class* java_lang_String, int32_t utf16_length) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001387 SirtRef<CharArray> array(CharArray::Alloc(utf16_length));
1388 if (array.get() == NULL) {
Elliott Hughesb51036c2011-10-12 23:49:11 -07001389 return NULL;
1390 }
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001391 return Alloc(java_lang_String, array.get());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001392}
1393
1394String* String::Alloc(Class* java_lang_String, CharArray* array) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001395 SirtRef<CharArray> array_ref(array); // hold reference in case AllocObject causes GC
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001396 String* string = down_cast<String*>(java_lang_String->AllocObject());
Elliott Hughesb51036c2011-10-12 23:49:11 -07001397 if (string == NULL) {
1398 return NULL;
1399 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001400 string->SetArray(array);
1401 string->SetCount(array->GetLength());
1402 return string;
1403}
1404
1405bool String::Equals(const String* that) const {
1406 if (this == that) {
1407 // Quick reference equality test
1408 return true;
1409 } else if (that == NULL) {
1410 // Null isn't an instanceof anything
1411 return false;
1412 } else if (this->GetLength() != that->GetLength()) {
1413 // Quick length inequality test
1414 return false;
1415 } else {
Elliott Hughes20cde902011-10-04 17:37:27 -07001416 // Note: don't short circuit on hash code as we're presumably here as the
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001417 // hash code was already equal
1418 for (int32_t i = 0; i < that->GetLength(); ++i) {
1419 if (this->CharAt(i) != that->CharAt(i)) {
1420 return false;
1421 }
1422 }
1423 return true;
1424 }
1425}
1426
1427bool String::Equals(const uint16_t* that_chars, int32_t that_offset,
1428 int32_t that_length) const {
1429 if (this->GetLength() != that_length) {
1430 return false;
1431 } else {
1432 for (int32_t i = 0; i < that_length; ++i) {
1433 if (this->CharAt(i) != that_chars[that_offset + i]) {
1434 return false;
1435 }
1436 }
1437 return true;
1438 }
1439}
1440
1441bool String::Equals(const char* modified_utf8) const {
1442 for (int32_t i = 0; i < GetLength(); ++i) {
1443 uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
1444 if (ch == '\0' || ch != CharAt(i)) {
1445 return false;
1446 }
1447 }
1448 return *modified_utf8 == '\0';
1449}
1450
1451bool String::Equals(const StringPiece& modified_utf8) const {
Elliott Hughes418d20f2011-09-22 14:00:39 -07001452 if (modified_utf8.size() != GetLength()) {
1453 return false;
1454 }
1455 const char* p = modified_utf8.data();
1456 for (int32_t i = 0; i < GetLength(); ++i) {
1457 uint16_t ch = GetUtf16FromUtf8(&p);
1458 if (ch != CharAt(i)) {
1459 return false;
1460 }
1461 }
1462 return true;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001463}
1464
1465// Create a modified UTF-8 encoded std::string from a java/lang/String object.
1466std::string String::ToModifiedUtf8() const {
1467 const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
1468 size_t byte_count(CountUtf8Bytes(chars, GetLength()));
1469 std::string result(byte_count, char(0));
1470 ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
1471 return result;
1472}
1473
Ian Rogers466bb252011-10-14 03:29:56 -07001474bool Throwable::IsCheckedException() const {
1475 Class* error = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Error;");
1476 if (InstanceOf(error)) {
1477 return false;
1478 }
1479 Class* jlre = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/RuntimeException;");
1480 return !InstanceOf(jlre);
1481}
1482
Ian Rogers9074b992011-10-26 17:41:55 -07001483std::string Throwable::Dump() const {
1484 Object* stack_state = GetStackState();
1485 if (stack_state == NULL || !stack_state->IsObjectArray()) {
1486 // missing or corrupt stack state
1487 return "";
1488 }
1489 // Decode the internal stack trace into the depth and method trace
1490 ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
1491 int32_t depth = method_trace->GetLength() - 1;
1492 std::string result;
1493 for (int32_t i = 0; i < depth; ++i) {
1494 Method* method = down_cast<Method*>(method_trace->Get(i));
1495 result += " at ";
1496 result += PrettyMethod(method, true);
1497 result += "\n";
1498 }
1499 return result;
1500}
1501
Shih-wei Liao55df06b2011-08-26 14:39:27 -07001502Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
1503
1504void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {
1505 CHECK(java_lang_StackTraceElement_ == NULL);
1506 CHECK(java_lang_StackTraceElement != NULL);
1507 java_lang_StackTraceElement_ = java_lang_StackTraceElement;
1508}
1509
1510void StackTraceElement::ResetClass() {
1511 CHECK(java_lang_StackTraceElement_ != NULL);
1512 java_lang_StackTraceElement_ = NULL;
1513}
1514
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001515StackTraceElement* StackTraceElement::Alloc(const String* declaring_class,
1516 const String* method_name,
1517 const String* file_name,
1518 int32_t line_number) {
1519 StackTraceElement* trace =
1520 down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject());
1521 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_),
1522 const_cast<String*>(declaring_class), false);
1523 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_),
1524 const_cast<String*>(method_name), false);
1525 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_),
1526 const_cast<String*>(file_name), false);
1527 trace->SetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_),
1528 line_number, false);
1529 return trace;
1530}
1531
Elliott Hughes1f359b02011-07-17 14:27:17 -07001532static const char* kClassStatusNames[] = {
1533 "Error",
1534 "NotReady",
1535 "Idx",
1536 "Loaded",
1537 "Resolved",
1538 "Verifying",
1539 "Verified",
1540 "Initializing",
1541 "Initialized"
1542};
1543std::ostream& operator<<(std::ostream& os, const Class::Status& rhs) {
1544 if (rhs >= Class::kStatusError && rhs <= Class::kStatusInitialized) {
Brian Carlstromae3ac012011-07-27 01:30:28 -07001545 os << kClassStatusNames[rhs + 1];
Elliott Hughes1f359b02011-07-17 14:27:17 -07001546 } else {
Ian Rogersb033c752011-07-20 12:22:35 -07001547 os << "Class::Status[" << static_cast<int>(rhs) << "]";
Elliott Hughes1f359b02011-07-17 14:27:17 -07001548 }
1549 return os;
1550}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001551
Carl Shapiro3ee755d2011-06-28 12:11:04 -07001552} // namespace art