blob: 78a1976c614359cd6f8aa995b23dafd82ede71e3 [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 Carlstrom5d40f182011-09-26 22:29:18 -0700770 DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
Brian Carlstrom1f870082011-08-23 16:02:11 -0700771 return Heap::AllocObject(this, this->object_size_);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700772}
773
Elliott Hughes4681c802011-09-25 18:04:37 -0700774void Class::DumpClass(std::ostream& os, int flags) const {
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700775 if ((flags & kDumpClassFullDetail) == 0) {
776 os << PrettyClass(this);
777 if ((flags & kDumpClassClassLoader) != 0) {
778 os << ' ' << GetClassLoader();
779 }
780 if ((flags & kDumpClassInitialized) != 0) {
781 os << ' ' << GetStatus();
782 }
783 os << std::endl;
784 return;
785 }
786
787 Class* super = GetSuperClass();
788 os << "----- " << (IsInterface() ? "interface" : "class") << " "
789 << "'" << GetDescriptor()->ToModifiedUtf8() << "' cl=" << GetClassLoader() << " -----\n",
790 os << " objectSize=" << SizeOf() << " "
791 << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n",
792 os << StringPrintf(" access=0x%04x.%04x\n",
793 GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
794 if (super != NULL) {
795 os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n";
796 }
797 if (IsArrayClass()) {
798 os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
799 }
800 if (NumInterfaces() > 0) {
801 os << " interfaces (" << NumInterfaces() << "):\n";
802 for (size_t i = 0; i < NumInterfaces(); ++i) {
803 Class* interface = GetInterface(i);
804 const ClassLoader* cl = interface->GetClassLoader();
805 os << StringPrintf(" %2d: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
806 }
807 }
808 os << " vtable (" << NumVirtualMethods() << " entries, "
809 << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n";
810 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
Elliott Hughes4681c802011-09-25 18:04:37 -0700811 os << StringPrintf(" %2d: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str());
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700812 }
813 os << " direct methods (" << NumDirectMethods() << " entries):\n";
814 for (size_t i = 0; i < NumDirectMethods(); ++i) {
815 os << StringPrintf(" %2d: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str());
816 }
817 if (NumStaticFields() > 0) {
818 os << " static fields (" << NumStaticFields() << " entries):\n";
Elliott Hughes03f03492011-09-26 13:38:08 -0700819 if (IsResolved() || IsErroneous()) {
Elliott Hughes4681c802011-09-25 18:04:37 -0700820 for (size_t i = 0; i < NumStaticFields(); ++i) {
Elliott Hughes03f03492011-09-26 13:38:08 -0700821 os << StringPrintf(" %2d: %s\n", i, PrettyField(GetStaticField(i)).c_str());
Elliott Hughes4681c802011-09-25 18:04:37 -0700822 }
823 } else {
824 os << " <not yet available>";
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700825 }
826 }
827 if (NumInstanceFields() > 0) {
828 os << " instance fields (" << NumInstanceFields() << " entries):\n";
Elliott Hughes03f03492011-09-26 13:38:08 -0700829 if (IsResolved() || IsErroneous()) {
Elliott Hughes4681c802011-09-25 18:04:37 -0700830 for (size_t i = 0; i < NumInstanceFields(); ++i) {
Elliott Hughes03f03492011-09-26 13:38:08 -0700831 os << StringPrintf(" %2d: %s\n", i, PrettyField(GetInstanceField(i)).c_str());
Elliott Hughes4681c802011-09-25 18:04:37 -0700832 }
833 } else {
834 os << " <not yet available>";
Elliott Hughes9d5ccec2011-09-19 13:19:50 -0700835 }
836 }
837}
838
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700839void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
840 if (new_reference_offsets != CLASS_WALK_SUPER) {
841 // Sanity check that the number of bits set in the reference offset bitmap
842 // agrees with the number of references
843 Class* cur = this;
844 size_t cnt = 0;
845 while (cur) {
846 cnt += cur->NumReferenceInstanceFieldsDuringLinking();
847 cur = cur->GetSuperClass();
848 }
849 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), cnt);
850 }
851 SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
852 new_reference_offsets, false);
853}
854
855void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
856 if (new_reference_offsets != CLASS_WALK_SUPER) {
857 // Sanity check that the number of bits set in the reference offset bitmap
858 // agrees with the number of references
859 CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets),
860 NumReferenceStaticFieldsDuringLinking());
861 }
862 SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
863 new_reference_offsets, false);
864}
865
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700866bool Class::Implements(const Class* klass) const {
867 DCHECK(klass != NULL);
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700868 DCHECK(klass->IsInterface()) << PrettyClass(this);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700869 // All interfaces implemented directly and by our superclass, and
870 // recursively all super-interfaces of those interfaces, are listed
871 // in iftable_, so we can just do a linear scan through that.
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700872 int32_t iftable_count = GetIfTableCount();
873 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
874 for (int32_t i = 0; i < iftable_count; i++) {
875 if (iftable->Get(i)->GetInterface() == klass) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700876 return true;
877 }
878 }
879 return false;
880}
881
882// Determine whether "this" is assignable from "klazz", where both of these
883// are array classes.
884//
885// Consider an array class, e.g. Y[][], where Y is a subclass of X.
886// Y[][] = Y[][] --> true (identity)
887// X[][] = Y[][] --> true (element superclass)
888// Y = Y[][] --> false
889// Y[] = Y[][] --> false
890// Object = Y[][] --> true (everything is an object)
891// Object[] = Y[][] --> true
892// Object[][] = Y[][] --> true
893// Object[][][] = Y[][] --> false (too many []s)
894// Serializable = Y[][] --> true (all arrays are Serializable)
895// Serializable[] = Y[][] --> true
896// Serializable[][] = Y[][] --> false (unless Y is Serializable)
897//
898// Don't forget about primitive types.
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700899// Object[] = int[] --> false
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700900//
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700901bool Class::IsArrayAssignableFromArray(const Class* src) const {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700902 DCHECK(IsArrayClass()) << PrettyClass(this);
903 DCHECK(src->IsArrayClass()) << PrettyClass(src);
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700904 return GetComponentType()->IsAssignableFrom(src->GetComponentType());
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700905}
906
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700907bool Class::IsAssignableFromArray(const Class* src) const {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700908 DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
909 DCHECK(src->IsArrayClass()) << PrettyClass(src);
Brian Carlstromb63ec392011-08-27 17:38:27 -0700910 if (!IsArrayClass()) {
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700911 // If "this" is not also an array, it must be Object.
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700912 // src's super should be java_lang_Object, since it is an array.
913 Class* java_lang_Object = src->GetSuperClass();
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700914 DCHECK(java_lang_Object != NULL) << PrettyClass(src);
915 DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700916 return this == java_lang_Object;
917 }
Brian Carlstrom5b8e4c82011-09-18 01:38:59 -0700918 return IsArrayAssignableFromArray(src);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700919}
920
921bool Class::IsSubClass(const Class* klass) const {
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700922 DCHECK(!IsInterface()) << PrettyClass(this);
923 DCHECK(!IsArrayClass()) << PrettyClass(this);
Brian Carlstromf7ed11a2011-08-09 17:55:51 -0700924 const Class* current = this;
925 do {
926 if (current == klass) {
927 return true;
928 }
929 current = current->GetSuperClass();
930 } while (current != NULL);
931 return false;
932}
933
Brian Carlstrom9cff8e12011-08-18 16:47:29 -0700934bool Class::IsInSamePackage(const String* descriptor_string_1,
935 const String* descriptor_string_2) {
936 const std::string descriptor1(descriptor_string_1->ToModifiedUtf8());
937 const std::string descriptor2(descriptor_string_2->ToModifiedUtf8());
938
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700939 size_t i = 0;
940 while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
941 ++i;
942 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700943 if (descriptor1.find('/', i) != StringPiece::npos ||
944 descriptor2.find('/', i) != StringPiece::npos) {
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700945 return false;
946 } else {
947 return true;
948 }
949}
950
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700951#if 0
Ian Rogersb033c752011-07-20 12:22:35 -0700952bool Class::IsInSamePackage(const StringPiece& descriptor1,
953 const StringPiece& descriptor2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700954 size_t size = std::min(descriptor1.size(), descriptor2.size());
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700955 std::pair<StringPiece::const_iterator, StringPiece::const_iterator> pos;
Ian Rogersb033c752011-07-20 12:22:35 -0700956 pos = std::mismatch(descriptor1.begin(), descriptor1.begin() + size,
957 descriptor2.begin());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700958 return !(*(pos.second).rfind('/') != npos && descriptor2.rfind('/') != npos);
959}
960#endif
961
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700962bool Class::IsInSamePackage(const Class* that) const {
963 const Class* klass1 = this;
964 const Class* klass2 = that;
965 if (klass1 == klass2) {
966 return true;
967 }
968 // Class loaders must match.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700969 if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700970 return false;
971 }
972 // Arrays are in the same package when their element classes are.
jeffhao4a801a42011-09-23 13:53:40 -0700973 while (klass1->IsArrayClass()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700974 klass1 = klass1->GetComponentType();
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700975 }
jeffhao4a801a42011-09-23 13:53:40 -0700976 while (klass2->IsArrayClass()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700977 klass2 = klass2->GetComponentType();
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700978 }
979 // Compare the package part of the descriptor string.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700980 return IsInSamePackage(klass1->descriptor_, klass2->descriptor_);
Carl Shapiro894d0fa2011-06-30 14:48:49 -0700981}
982
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700983const ClassLoader* Class::GetClassLoader() const {
Ian Rogersd81871c2011-10-03 13:57:23 -0700984 return GetFieldObject<const ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
Brian Carlstromb9edb842011-08-28 16:31:06 -0700985}
986
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700987void Class::SetClassLoader(const ClassLoader* new_cl) {
988 ClassLoader* new_class_loader = const_cast<ClassLoader*>(new_cl);
Ian Rogersd81871c2011-10-03 13:57:23 -0700989 SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
Carl Shapiro8860c0e2011-08-04 17:36:16 -0700990}
991
Ian Rogersb04f69f2011-10-17 00:40:54 -0700992Method* Class::FindVirtualMethodForInterface(Method* method, bool can_throw) {
Brian Carlstrom30b94452011-08-25 21:35:26 -0700993 Class* declaring_class = method->GetDeclaringClass();
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700994 DCHECK(declaring_class != NULL) << PrettyClass(this);
995 DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
Brian Carlstrom30b94452011-08-25 21:35:26 -0700996 // TODO cache to improve lookup speed
Brian Carlstrom4b620ff2011-09-11 01:11:01 -0700997 int32_t iftable_count = GetIfTableCount();
998 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
999 for (int32_t i = 0; i < iftable_count; i++) {
1000 InterfaceEntry* interface_entry = iftable->Get(i);
1001 if (interface_entry->GetInterface() == declaring_class) {
1002 return interface_entry->GetMethodArray()->Get(method->GetMethodIndex());
Brian Carlstrom30b94452011-08-25 21:35:26 -07001003 }
1004 }
Ian Rogersb04f69f2011-10-17 00:40:54 -07001005 if (can_throw) {
1006 Thread::Current()->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
1007 "Class %s does not implement interface %s",
1008 PrettyDescriptor(GetDescriptor()).c_str(),
1009 PrettyDescriptor(declaring_class->GetDescriptor()).c_str());
1010 }
Brian Carlstrom30b94452011-08-25 21:35:26 -07001011 return NULL;
1012}
1013
Ian Rogers466bb252011-10-14 03:29:56 -07001014Method* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const {
jeffhaobdb76512011-09-07 11:43:16 -07001015 // Check the current class before checking the interfaces.
1016 Method* method = FindVirtualMethod(name, signature);
1017 if (method != NULL) {
1018 return method;
1019 }
1020
Brian Carlstrom4b620ff2011-09-11 01:11:01 -07001021 int32_t iftable_count = GetIfTableCount();
1022 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
1023 for (int32_t i = 0; i < iftable_count; i++) {
1024 method = iftable->Get(i)->GetInterface()->FindVirtualMethod(name, signature);
jeffhaobdb76512011-09-07 11:43:16 -07001025 if (method != NULL) {
1026 return method;
1027 }
1028 }
1029 return NULL;
1030}
1031
Ian Rogers466bb252011-10-14 03:29:56 -07001032Method* Class::FindInterfaceMethod(String* name, String* signature) const {
1033 // Check the current class before checking the interfaces.
1034 Method* method = FindVirtualMethod(name, signature);
1035 if (method != NULL) {
1036 return method;
1037 }
1038 int32_t iftable_count = GetIfTableCount();
1039 ObjectArray<InterfaceEntry>* iftable = GetIfTable();
1040 for (int32_t i = 0; i < iftable_count; i++) {
1041 Class* interface = iftable->Get(i)->GetInterface();
1042 method = interface->FindVirtualMethod(name, signature);
1043 if (method != NULL) {
1044 return method;
1045 }
1046 }
1047 return NULL;
1048}
1049
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001050Method* Class::FindDeclaredDirectMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001051 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001052 for (size_t i = 0; i < NumDirectMethods(); ++i) {
Ian Rogersb033c752011-07-20 12:22:35 -07001053 Method* method = GetDirectMethod(i);
Carl Shapiro8860c0e2011-08-04 17:36:16 -07001054 if (method->GetName()->Equals(name) &&
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001055 method->GetSignature()->Equals(signature)) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001056 return method;
Ian Rogersb033c752011-07-20 12:22:35 -07001057 }
1058 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001059 return NULL;
Ian Rogersb033c752011-07-20 12:22:35 -07001060}
1061
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001062Method* Class::FindDirectMethod(const StringPiece& name,
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001063 const StringPiece& signature) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001064 for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
Brian Carlstrom9cff8e12011-08-18 16:47:29 -07001065 Method* method = klass->FindDeclaredDirectMethod(name, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001066 if (method != NULL) {
1067 return method;
1068 }
1069 }
1070 return NULL;
1071}
1072
1073Method* Class::FindDeclaredVirtualMethod(const StringPiece& name,
Ian Rogers466bb252011-10-14 03:29:56 -07001074 const StringPiece& signature) const {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001075 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
Ian Rogersb033c752011-07-20 12:22:35 -07001076 Method* method = GetVirtualMethod(i);
Ian Rogers466bb252011-10-14 03:29:56 -07001077 if (method->GetName()->Equals(name) && method->GetSignature()->Equals(signature)) {
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001078 return method;
Ian Rogersb033c752011-07-20 12:22:35 -07001079 }
1080 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001081 return NULL;
Ian Rogersb033c752011-07-20 12:22:35 -07001082}
1083
Ian Rogers466bb252011-10-14 03:29:56 -07001084Method* Class::FindDeclaredVirtualMethod(String* name, String* signature) const {
1085 for (size_t i = 0; i < NumVirtualMethods(); ++i) {
1086 Method* method = GetVirtualMethod(i);
1087 if (method->GetName() == name && method->GetSignature() == signature) {
1088 return method;
Ian Rogers466bb252011-10-14 03:29:56 -07001089 }
1090 }
1091 return NULL;
1092}
1093
1094Method* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
1095 for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
1096 Method* method = klass->FindDeclaredVirtualMethod(name, signature);
1097 if (method != NULL) {
1098 return method;
1099 }
1100 }
1101 return NULL;
1102}
1103
1104Method* Class::FindVirtualMethod(String* name, String* signature) const {
1105 for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
Elliott Hughescc5f9a92011-09-28 19:17:29 -07001106 Method* method = klass->FindDeclaredVirtualMethod(name, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001107 if (method != NULL) {
1108 return method;
1109 }
1110 }
1111 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001112}
1113
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001114Field* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001115 // Is the field in this class?
1116 // Interfaces are not relevant because they can't contain instance fields.
1117 for (size_t i = 0; i < NumInstanceFields(); ++i) {
1118 Field* f = GetInstanceField(i);
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001119 if (f->GetName()->Equals(name) &&
1120 StringPiece(f->GetTypeDescriptor()) == type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001121 return f;
1122 }
1123 }
1124 return NULL;
1125}
1126
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001127Field* Class::FindDeclaredInstanceField(String* name, String* type) {
1128 // Is the field in this class?
1129 // Interfaces are not relevant because they can't contain instance fields.
1130 for (size_t i = 0; i < NumInstanceFields(); ++i) {
1131 Field* f = GetInstanceField(i);
1132 if (f->GetName() == name && type->Equals(f->GetTypeDescriptor())) {
1133 return f;
1134 }
1135 }
1136 return NULL;
1137}
1138
1139Field* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001140 // Is the field in this class, or any of its superclasses?
1141 // Interfaces are not relevant because they can't contain instance fields.
1142 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001143 Field* f = c->FindDeclaredInstanceField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -07001144 if (f != NULL) {
1145 return f;
1146 }
1147 }
1148 return NULL;
1149}
1150
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001151Field* Class::FindInstanceField(String* name, String* type) {
1152 // Is the field in this class, or any of its superclasses?
1153 // Interfaces are not relevant because they can't contain instance fields.
1154 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
1155 Field* f = c->FindDeclaredInstanceField(name, type);
1156 if (f != NULL) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001157 return f;
1158 }
1159 }
1160 return NULL;
1161}
1162
Brian Carlstrom6b4ef022011-10-23 14:59:04 -07001163Field* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
1164 DCHECK(type != NULL);
1165 for (size_t i = 0; i < NumStaticFields(); ++i) {
1166 Field* f = GetStaticField(i);
1167 if (f->GetName()->Equals(name) && StringPiece(f->GetTypeDescriptor()) == type) {
1168 return f;
1169 }
1170 }
1171 return NULL;
1172}
1173
1174Field* Class::FindDeclaredStaticField(String* name, String* type) {
1175 DCHECK(type != NULL);
1176 for (size_t i = 0; i < NumStaticFields(); ++i) {
1177 Field* f = GetStaticField(i);
1178 if (f->GetName() == name && type->Equals(f->GetTypeDescriptor())) {
1179 return f;
1180 }
1181 }
1182 return NULL;
1183}
1184
1185Field* Class::FindStaticField(const StringPiece& name, const StringPiece& type) {
1186 // Is the field in this class (or its interfaces), or any of its
1187 // superclasses (or their interfaces)?
1188 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
1189 // Is the field in this class?
1190 Field* f = c->FindDeclaredStaticField(name, type);
1191 if (f != NULL) {
1192 return f;
1193 }
1194
1195 // Is this field in any of this class' interfaces?
1196 for (int32_t i = 0; i < c->GetIfTableCount(); ++i) {
1197 InterfaceEntry* interface_entry = c->GetIfTable()->Get(i);
1198 Class* interface = interface_entry->GetInterface();
1199 f = interface->FindDeclaredStaticField(name, type);
1200 if (f != NULL) {
1201 return f;
1202 }
1203 }
1204 }
1205 return NULL;
1206}
1207
1208Field* Class::FindStaticField(String* name, String* type) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001209 // Is the field in this class (or its interfaces), or any of its
1210 // superclasses (or their interfaces)?
1211 for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
1212 // Is the field in this class?
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001213 Field* f = c->FindDeclaredStaticField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -07001214 if (f != NULL) {
1215 return f;
1216 }
1217
1218 // Is this field in any of this class' interfaces?
jeffhaoe0cfb6f2011-09-22 16:42:56 -07001219 for (int32_t i = 0; i < c->GetIfTableCount(); ++i) {
1220 InterfaceEntry* interface_entry = c->GetIfTable()->Get(i);
1221 Class* interface = interface_entry->GetInterface();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001222 f = interface->FindDeclaredStaticField(name, type);
Elliott Hughescdf53122011-08-19 15:46:09 -07001223 if (f != NULL) {
1224 return f;
1225 }
1226 }
1227 }
1228 return NULL;
1229}
1230
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001231Array* Array::Alloc(Class* array_class, int32_t component_count, size_t component_size) {
Elliott Hughes0f4c41d2011-09-04 14:58:03 -07001232 DCHECK(array_class != NULL);
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001233 DCHECK_GE(component_count, 0);
1234 DCHECK(array_class->IsArrayClass());
Elliott Hughesb408de72011-10-04 14:35:05 -07001235
1236 size_t header_size = sizeof(Array);
1237 size_t data_size = component_count * component_size;
1238 size_t size = header_size + data_size;
1239
1240 // Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
1241 size_t component_shift = sizeof(size_t) * 8 - 1 - CLZ(component_size);
1242 if (data_size >> component_shift != size_t(component_count) || size < data_size) {
1243 Thread::Current()->ThrowNewExceptionF("Ljava/lang/OutOfMemoryError;",
1244 "%s of length %zd exceeds the VM limit",
1245 PrettyDescriptor(array_class->GetDescriptor()).c_str(), component_count);
1246 return NULL;
1247 }
1248
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001249 Array* array = down_cast<Array*>(Heap::AllocObject(array_class, size));
1250 if (array != NULL) {
1251 DCHECK(array->IsArrayInstance());
1252 array->SetLength(component_count);
1253 }
1254 return array;
1255}
1256
1257Array* Array::Alloc(Class* array_class, int32_t component_count) {
1258 return Alloc(array_class, component_count, array_class->GetComponentSize());
1259}
1260
Elliott Hughes80609252011-09-23 17:24:51 -07001261bool Array::ThrowArrayIndexOutOfBoundsException(int32_t index) const {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001262 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Elliott Hughes80609252011-09-23 17:24:51 -07001263 "length=%i; index=%i", length_, index);
1264 return false;
1265}
1266
1267bool Array::ThrowArrayStoreException(Object* object) const {
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001268 Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
Elliott Hughes80609252011-09-23 17:24:51 -07001269 "Can't store an element of type %s into an array of type %s",
1270 PrettyTypeOf(object).c_str(), PrettyTypeOf(this).c_str());
1271 return false;
1272}
1273
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001274template<typename T>
1275PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
Elliott Hughesc1674ed2011-08-25 18:09:09 -07001276 DCHECK(array_class_ != NULL);
Elliott Hughesd8ddfd52011-08-15 14:32:53 -07001277 Array* raw_array = Array::Alloc(array_class_, length, sizeof(T));
1278 return down_cast<PrimitiveArray<T>*>(raw_array);
1279}
1280
1281template <typename T> Class* PrimitiveArray<T>::array_class_ = NULL;
1282
1283// Explicitly instantiate all the primitive array types.
1284template class PrimitiveArray<uint8_t>; // BooleanArray
1285template class PrimitiveArray<int8_t>; // ByteArray
1286template class PrimitiveArray<uint16_t>; // CharArray
1287template class PrimitiveArray<double>; // DoubleArray
1288template class PrimitiveArray<float>; // FloatArray
1289template class PrimitiveArray<int32_t>; // IntArray
1290template class PrimitiveArray<int64_t>; // LongArray
1291template class PrimitiveArray<int16_t>; // ShortArray
1292
Ian Rogers466bb252011-10-14 03:29:56 -07001293// Explicitly instantiate Class[][]
1294template class ObjectArray<ObjectArray<Class> >;
1295
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001296// TODO: get global references for these
1297Class* String::java_lang_String_ = NULL;
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001298
Brian Carlstroma663ea52011-08-19 23:33:41 -07001299void String::SetClass(Class* java_lang_String) {
1300 CHECK(java_lang_String_ == NULL);
1301 CHECK(java_lang_String != NULL);
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001302 java_lang_String_ = java_lang_String;
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001303}
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001304
Brian Carlstroma663ea52011-08-19 23:33:41 -07001305void String::ResetClass() {
1306 CHECK(java_lang_String_ != NULL);
1307 java_lang_String_ = NULL;
1308}
Jesse Wilsonf7e85a52011-08-01 18:45:58 -07001309
Brian Carlstromc74255f2011-09-11 22:47:39 -07001310String* String::Intern() {
Elliott Hughescf4c6c42011-09-01 15:16:42 -07001311 return Runtime::Current()->GetInternTable()->InternWeak(this);
1312}
1313
Brian Carlstrom395520e2011-09-25 19:35:00 -07001314int32_t String::GetHashCode() {
1315 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
1316 if (result == 0) {
1317 ComputeHashCode();
1318 }
1319 result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
1320 DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
1321 << ToModifiedUtf8() << " " << result;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001322 return result;
1323}
1324
1325int32_t String::GetLength() const {
1326 int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
1327 DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
1328 return result;
1329}
1330
1331uint16_t String::CharAt(int32_t index) const {
1332 // TODO: do we need this? Equals is the only caller, and could
1333 // bounds check itself.
1334 if (index < 0 || index >= count_) {
1335 Thread* self = Thread::Current();
Elliott Hughes5cb5ad22011-10-02 12:13:39 -07001336 self->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001337 "length=%i; index=%i", count_, index);
1338 return 0;
1339 }
1340 return GetCharArray()->Get(index + GetOffset());
1341}
1342
1343String* String::AllocFromUtf16(int32_t utf16_length,
1344 const uint16_t* utf16_data_in,
1345 int32_t hash_code) {
1346 String* string = Alloc(GetJavaLangString(), utf16_length);
Elliott Hughesb51036c2011-10-12 23:49:11 -07001347 if (string == NULL) {
1348 return NULL;
1349 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001350 // TODO: use 16-bit wide memset variant
1351 CharArray* array = const_cast<CharArray*>(string->GetCharArray());
Elliott Hughesb51036c2011-10-12 23:49:11 -07001352 if (array == NULL) {
1353 return NULL;
1354 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001355 for (int i = 0; i < utf16_length; i++) {
1356 array->Set(i, utf16_data_in[i]);
1357 }
1358 if (hash_code != 0) {
1359 string->SetHashCode(hash_code);
1360 } else {
1361 string->ComputeHashCode();
1362 }
1363 return string;
1364}
1365
1366String* String::AllocFromModifiedUtf8(const char* utf) {
1367 size_t char_count = CountModifiedUtf8Chars(utf);
1368 return AllocFromModifiedUtf8(char_count, utf);
1369}
1370
1371String* String::AllocFromModifiedUtf8(int32_t utf16_length,
1372 const char* utf8_data_in) {
1373 String* string = Alloc(GetJavaLangString(), utf16_length);
Elliott Hughesb51036c2011-10-12 23:49:11 -07001374 if (string == NULL) {
1375 return NULL;
1376 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001377 uint16_t* utf16_data_out =
1378 const_cast<uint16_t*>(string->GetCharArray()->GetData());
1379 ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
1380 string->ComputeHashCode();
1381 return string;
1382}
1383
1384String* String::Alloc(Class* java_lang_String, int32_t utf16_length) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001385 SirtRef<CharArray> array(CharArray::Alloc(utf16_length));
1386 if (array.get() == NULL) {
Elliott Hughesb51036c2011-10-12 23:49:11 -07001387 return NULL;
1388 }
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001389 return Alloc(java_lang_String, array.get());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001390}
1391
1392String* String::Alloc(Class* java_lang_String, CharArray* array) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001393 SirtRef<CharArray> array_ref(array); // hold reference in case AllocObject causes GC
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001394 String* string = down_cast<String*>(java_lang_String->AllocObject());
Elliott Hughesb51036c2011-10-12 23:49:11 -07001395 if (string == NULL) {
1396 return NULL;
1397 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001398 string->SetArray(array);
1399 string->SetCount(array->GetLength());
1400 return string;
1401}
1402
1403bool String::Equals(const String* that) const {
1404 if (this == that) {
1405 // Quick reference equality test
1406 return true;
1407 } else if (that == NULL) {
1408 // Null isn't an instanceof anything
1409 return false;
1410 } else if (this->GetLength() != that->GetLength()) {
1411 // Quick length inequality test
1412 return false;
1413 } else {
Elliott Hughes20cde902011-10-04 17:37:27 -07001414 // Note: don't short circuit on hash code as we're presumably here as the
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001415 // hash code was already equal
1416 for (int32_t i = 0; i < that->GetLength(); ++i) {
1417 if (this->CharAt(i) != that->CharAt(i)) {
1418 return false;
1419 }
1420 }
1421 return true;
1422 }
1423}
1424
1425bool String::Equals(const uint16_t* that_chars, int32_t that_offset,
1426 int32_t that_length) const {
1427 if (this->GetLength() != that_length) {
1428 return false;
1429 } else {
1430 for (int32_t i = 0; i < that_length; ++i) {
1431 if (this->CharAt(i) != that_chars[that_offset + i]) {
1432 return false;
1433 }
1434 }
1435 return true;
1436 }
1437}
1438
1439bool String::Equals(const char* modified_utf8) const {
1440 for (int32_t i = 0; i < GetLength(); ++i) {
1441 uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
1442 if (ch == '\0' || ch != CharAt(i)) {
1443 return false;
1444 }
1445 }
1446 return *modified_utf8 == '\0';
1447}
1448
1449bool String::Equals(const StringPiece& modified_utf8) const {
Elliott Hughes418d20f2011-09-22 14:00:39 -07001450 if (modified_utf8.size() != GetLength()) {
1451 return false;
1452 }
1453 const char* p = modified_utf8.data();
1454 for (int32_t i = 0; i < GetLength(); ++i) {
1455 uint16_t ch = GetUtf16FromUtf8(&p);
1456 if (ch != CharAt(i)) {
1457 return false;
1458 }
1459 }
1460 return true;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001461}
1462
1463// Create a modified UTF-8 encoded std::string from a java/lang/String object.
1464std::string String::ToModifiedUtf8() const {
1465 const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
1466 size_t byte_count(CountUtf8Bytes(chars, GetLength()));
1467 std::string result(byte_count, char(0));
1468 ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
1469 return result;
1470}
1471
Ian Rogers466bb252011-10-14 03:29:56 -07001472bool Throwable::IsCheckedException() const {
1473 Class* error = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Error;");
1474 if (InstanceOf(error)) {
1475 return false;
1476 }
1477 Class* jlre = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/RuntimeException;");
1478 return !InstanceOf(jlre);
1479}
1480
Ian Rogers9074b992011-10-26 17:41:55 -07001481std::string Throwable::Dump() const {
1482 Object* stack_state = GetStackState();
1483 if (stack_state == NULL || !stack_state->IsObjectArray()) {
1484 // missing or corrupt stack state
1485 return "";
1486 }
1487 // Decode the internal stack trace into the depth and method trace
1488 ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
1489 int32_t depth = method_trace->GetLength() - 1;
1490 std::string result;
1491 for (int32_t i = 0; i < depth; ++i) {
1492 Method* method = down_cast<Method*>(method_trace->Get(i));
1493 result += " at ";
1494 result += PrettyMethod(method, true);
1495 result += "\n";
1496 }
1497 return result;
1498}
1499
Shih-wei Liao55df06b2011-08-26 14:39:27 -07001500Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
1501
1502void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {
1503 CHECK(java_lang_StackTraceElement_ == NULL);
1504 CHECK(java_lang_StackTraceElement != NULL);
1505 java_lang_StackTraceElement_ = java_lang_StackTraceElement;
1506}
1507
1508void StackTraceElement::ResetClass() {
1509 CHECK(java_lang_StackTraceElement_ != NULL);
1510 java_lang_StackTraceElement_ = NULL;
1511}
1512
Ian Rogers0cfe1fb2011-08-26 03:29:44 -07001513StackTraceElement* StackTraceElement::Alloc(const String* declaring_class,
1514 const String* method_name,
1515 const String* file_name,
1516 int32_t line_number) {
1517 StackTraceElement* trace =
1518 down_cast<StackTraceElement*>(GetStackTraceElement()->AllocObject());
1519 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_),
1520 const_cast<String*>(declaring_class), false);
1521 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_),
1522 const_cast<String*>(method_name), false);
1523 trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_),
1524 const_cast<String*>(file_name), false);
1525 trace->SetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_),
1526 line_number, false);
1527 return trace;
1528}
1529
Elliott Hughes1f359b02011-07-17 14:27:17 -07001530static const char* kClassStatusNames[] = {
1531 "Error",
1532 "NotReady",
1533 "Idx",
1534 "Loaded",
1535 "Resolved",
1536 "Verifying",
1537 "Verified",
1538 "Initializing",
1539 "Initialized"
1540};
1541std::ostream& operator<<(std::ostream& os, const Class::Status& rhs) {
1542 if (rhs >= Class::kStatusError && rhs <= Class::kStatusInitialized) {
Brian Carlstromae3ac012011-07-27 01:30:28 -07001543 os << kClassStatusNames[rhs + 1];
Elliott Hughes1f359b02011-07-17 14:27:17 -07001544 } else {
Ian Rogersb033c752011-07-20 12:22:35 -07001545 os << "Class::Status[" << static_cast<int>(rhs) << "]";
Elliott Hughes1f359b02011-07-17 14:27:17 -07001546 }
1547 return os;
1548}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001549
Carl Shapiro3ee755d2011-06-28 12:11:04 -07001550} // namespace art