1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "object.h"
18
19#include <stdint.h>
20#include <stdio.h>
21
22#include "array-inl.h"
23#include "art_field-inl.h"
24#include "asm_support.h"
25#include "class-inl.h"
26#include "class_linker.h"
27#include "class_linker-inl.h"
28#include "common_test.h"
29#include "dex_file.h"
30#include "entrypoints/entrypoint_utils.h"
31#include "gc/accounting/card_table-inl.h"
32#include "gc/heap.h"
33#include "iftable-inl.h"
34#include "art_method-inl.h"
35#include "object-inl.h"
36#include "object_array-inl.h"
37#include "sirt_ref.h"
38#include "UniquePtr.h"
39
40namespace art {
41namespace mirror {
42
43class ObjectTest : public CommonTest {
44 protected:
45  void AssertString(int32_t expected_utf16_length,
46                    const char* utf8_in,
47                    const char* utf16_expected_le,
48                    int32_t expected_hash)
49      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
50    UniquePtr<uint16_t[]> utf16_expected(new uint16_t[expected_utf16_length]);
51    for (int32_t i = 0; i < expected_utf16_length; i++) {
52      uint16_t ch = (((utf16_expected_le[i*2 + 0] & 0xff) << 8) |
53                     ((utf16_expected_le[i*2 + 1] & 0xff) << 0));
54      utf16_expected[i] = ch;
55    }
56
57    Thread* self = Thread::Current();
58    SirtRef<String> string(self, String::AllocFromModifiedUtf8(self, expected_utf16_length, utf8_in));
59    ASSERT_EQ(expected_utf16_length, string->GetLength());
60    ASSERT_TRUE(string->GetCharArray() != NULL);
61    ASSERT_TRUE(string->GetCharArray()->GetData() != NULL);
62    // strlen is necessary because the 1-character string "\x00\x00" is interpreted as ""
63    ASSERT_TRUE(string->Equals(utf8_in) || (expected_utf16_length == 1 && strlen(utf8_in) == 0));
64    ASSERT_TRUE(string->Equals(StringPiece(utf8_in)) || (expected_utf16_length == 1 && strlen(utf8_in) == 0));
65    for (int32_t i = 0; i < expected_utf16_length; i++) {
66      EXPECT_EQ(utf16_expected[i], string->CharAt(i));
67    }
68    EXPECT_EQ(expected_hash, string->GetHashCode());
69  }
70};
71
72// Keep the assembly code in sync
73TEST_F(ObjectTest, AsmConstants) {
74  ASSERT_EQ(STRING_VALUE_OFFSET, String::ValueOffset().Int32Value());
75  ASSERT_EQ(STRING_COUNT_OFFSET, String::CountOffset().Int32Value());
76  ASSERT_EQ(STRING_OFFSET_OFFSET, String::OffsetOffset().Int32Value());
77  ASSERT_EQ(STRING_DATA_OFFSET, Array::DataOffset(sizeof(uint16_t)).Int32Value());
78
79  ASSERT_EQ(METHOD_CODE_OFFSET, ArtMethod::EntryPointFromCompiledCodeOffset().Int32Value());
80}
81
82TEST_F(ObjectTest, IsInSamePackage) {
83  // Matches
84  EXPECT_TRUE(Class::IsInSamePackage("Ljava/lang/Object;", "Ljava/lang/Class;"));
85  EXPECT_TRUE(Class::IsInSamePackage("LFoo;", "LBar;"));
86
87  // Mismatches
88  EXPECT_FALSE(Class::IsInSamePackage("Ljava/lang/Object;", "Ljava/io/File;"));
89  EXPECT_FALSE(Class::IsInSamePackage("Ljava/lang/Object;", "Ljava/lang/reflect/Method;"));
90}
91
92TEST_F(ObjectTest, Clone) {
93  ScopedObjectAccess soa(Thread::Current());
94  SirtRef<ObjectArray<Object> > a1(soa.Self(),
95                                   class_linker_->AllocObjectArray<Object>(soa.Self(), 256));
96  size_t s1 = a1->SizeOf();
97  Object* clone = a1->Clone(soa.Self());
98  EXPECT_EQ(s1, clone->SizeOf());
99  EXPECT_TRUE(clone->GetClass() == a1->GetClass());
100}
101
102TEST_F(ObjectTest, AllocObjectArray) {
103  ScopedObjectAccess soa(Thread::Current());
104  SirtRef<ObjectArray<Object> > oa(soa.Self(),
105                                   class_linker_->AllocObjectArray<Object>(soa.Self(), 2));
106  EXPECT_EQ(2, oa->GetLength());
107  EXPECT_TRUE(oa->Get(0) == NULL);
108  EXPECT_TRUE(oa->Get(1) == NULL);
109  oa->Set(0, oa.get());
110  EXPECT_TRUE(oa->Get(0) == oa.get());
111  EXPECT_TRUE(oa->Get(1) == NULL);
112  oa->Set(1, oa.get());
113  EXPECT_TRUE(oa->Get(0) == oa.get());
114  EXPECT_TRUE(oa->Get(1) == oa.get());
115
116  Class* aioobe = class_linker_->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;");
117
118  EXPECT_TRUE(oa->Get(-1) == NULL);
119  EXPECT_TRUE(soa.Self()->IsExceptionPending());
120  EXPECT_EQ(aioobe, soa.Self()->GetException(NULL)->GetClass());
121  soa.Self()->ClearException();
122
123  EXPECT_TRUE(oa->Get(2) == NULL);
124  EXPECT_TRUE(soa.Self()->IsExceptionPending());
125  EXPECT_EQ(aioobe, soa.Self()->GetException(NULL)->GetClass());
126  soa.Self()->ClearException();
127
128  ASSERT_TRUE(oa->GetClass() != NULL);
129  ClassHelper oa_ch(oa->GetClass());
130  ASSERT_EQ(2U, oa_ch.NumDirectInterfaces());
131  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/lang/Cloneable;"), oa_ch.GetDirectInterface(0));
132  EXPECT_EQ(class_linker_->FindSystemClass("Ljava/io/Serializable;"), oa_ch.GetDirectInterface(1));
133}
134
135TEST_F(ObjectTest, AllocArray) {
136  ScopedObjectAccess soa(Thread::Current());
137  Class* c = class_linker_->FindSystemClass("[I");
138  SirtRef<Array> a(soa.Self(), Array::Alloc(soa.Self(), c, 1));
139  ASSERT_TRUE(c == a->GetClass());
140
141  c = class_linker_->FindSystemClass("[Ljava/lang/Object;");
142  a.reset(Array::Alloc(soa.Self(), c, 1));
143  ASSERT_TRUE(c == a->GetClass());
144
145  c = class_linker_->FindSystemClass("[[Ljava/lang/Object;");
146  a.reset(Array::Alloc(soa.Self(), c, 1));
147  ASSERT_TRUE(c == a->GetClass());
148}
149
150template<typename ArrayT>
151void TestPrimitiveArray(ClassLinker* cl) {
152  ScopedObjectAccess soa(Thread::Current());
153  typedef typename ArrayT::ElementType T;
154
155  ArrayT* a = ArrayT::Alloc(soa.Self(), 2);
156  EXPECT_EQ(2, a->GetLength());
157  EXPECT_EQ(0, a->Get(0));
158  EXPECT_EQ(0, a->Get(1));
159  a->Set(0, T(123));
160  EXPECT_EQ(T(123), a->Get(0));
161  EXPECT_EQ(0, a->Get(1));
162  a->Set(1, T(321));
163  EXPECT_EQ(T(123), a->Get(0));
164  EXPECT_EQ(T(321), a->Get(1));
165
166  Class* aioobe = cl->FindSystemClass("Ljava/lang/ArrayIndexOutOfBoundsException;");
167
168  EXPECT_EQ(0, a->Get(-1));
169  EXPECT_TRUE(soa.Self()->IsExceptionPending());
170  EXPECT_EQ(aioobe, soa.Self()->GetException(NULL)->GetClass());
171  soa.Self()->ClearException();
172
173  EXPECT_EQ(0, a->Get(2));
174  EXPECT_TRUE(soa.Self()->IsExceptionPending());
175  EXPECT_EQ(aioobe, soa.Self()->GetException(NULL)->GetClass());
176  soa.Self()->ClearException();
177}
178
179TEST_F(ObjectTest, PrimitiveArray_Boolean_Alloc) {
180  TestPrimitiveArray<BooleanArray>(class_linker_);
181}
182TEST_F(ObjectTest, PrimitiveArray_Byte_Alloc) {
183  TestPrimitiveArray<ByteArray>(class_linker_);
184}
185TEST_F(ObjectTest, PrimitiveArray_Char_Alloc) {
186  TestPrimitiveArray<CharArray>(class_linker_);
187}
188TEST_F(ObjectTest, PrimitiveArray_Double_Alloc) {
189  TestPrimitiveArray<DoubleArray>(class_linker_);
190}
191TEST_F(ObjectTest, PrimitiveArray_Float_Alloc) {
192  TestPrimitiveArray<FloatArray>(class_linker_);
193}
194TEST_F(ObjectTest, PrimitiveArray_Int_Alloc) {
195  TestPrimitiveArray<IntArray>(class_linker_);
196}
197TEST_F(ObjectTest, PrimitiveArray_Long_Alloc) {
198  TestPrimitiveArray<LongArray>(class_linker_);
199}
200TEST_F(ObjectTest, PrimitiveArray_Short_Alloc) {
201  TestPrimitiveArray<ShortArray>(class_linker_);
202}
203
204TEST_F(ObjectTest, CheckAndAllocArrayFromCode) {
205  // pretend we are trying to call 'new char[3]' from String.toCharArray
206  ScopedObjectAccess soa(Thread::Current());
207  Class* java_util_Arrays = class_linker_->FindSystemClass("Ljava/util/Arrays;");
208  ArtMethod* sort = java_util_Arrays->FindDirectMethod("sort", "([I)V");
209  const DexFile::StringId* string_id = java_lang_dex_file_->FindStringId("[I");
210  ASSERT_TRUE(string_id != NULL);
211  const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(
212      java_lang_dex_file_->GetIndexForStringId(*string_id));
213  ASSERT_TRUE(type_id != NULL);
214  uint32_t type_idx = java_lang_dex_file_->GetIndexForTypeId(*type_id);
215  Object* array = CheckAndAllocArrayFromCode(type_idx, sort, 3, Thread::Current(), false);
216  EXPECT_TRUE(array->IsArrayInstance());
217  EXPECT_EQ(3, array->AsArray()->GetLength());
218  EXPECT_TRUE(array->GetClass()->IsArrayClass());
219  EXPECT_TRUE(array->GetClass()->GetComponentType()->IsPrimitive());
220}
221
222TEST_F(ObjectTest, CreateMultiArray) {
223  ScopedObjectAccess soa(Thread::Current());
224
225  SirtRef<Class> c(soa.Self(), class_linker_->FindSystemClass("I"));
226  SirtRef<IntArray> dims(soa.Self(), IntArray::Alloc(soa.Self(), 1));
227  dims->Set(0, 1);
228  Array* multi = Array::CreateMultiArray(soa.Self(), c.get(), dims.get());
229  EXPECT_TRUE(multi->GetClass() == class_linker_->FindSystemClass("[I"));
230  EXPECT_EQ(1, multi->GetLength());
231
232  dims->Set(0, -1);
233  multi = Array::CreateMultiArray(soa.Self(), c.get(), dims.get());
234  EXPECT_TRUE(soa.Self()->IsExceptionPending());
235  EXPECT_EQ(PrettyDescriptor(soa.Self()->GetException(NULL)->GetClass()),
236            "java.lang.NegativeArraySizeException");
237  soa.Self()->ClearException();
238
239  dims.reset(IntArray::Alloc(soa.Self(), 2));
240  for (int i = 1; i < 20; ++i) {
241    for (int j = 0; j < 20; ++j) {
242      dims->Set(0, i);
243      dims->Set(1, j);
244      multi = Array::CreateMultiArray(soa.Self(), c.get(), dims.get());
245      EXPECT_TRUE(multi->GetClass() == class_linker_->FindSystemClass("[[I"));
246      EXPECT_EQ(i, multi->GetLength());
247      for (int k = 0; k < i; ++k) {
248        Array* outer = multi->AsObjectArray<Array>()->Get(k);
249        EXPECT_TRUE(outer->GetClass() == class_linker_->FindSystemClass("[I"));
250        EXPECT_EQ(j, outer->GetLength());
251      }
252    }
253  }
254}
255
256TEST_F(ObjectTest, StaticFieldFromCode) {
257  // pretend we are trying to access 'Static.s0' from StaticsFromCode.<clinit>
258  ScopedObjectAccess soa(Thread::Current());
259  jobject class_loader = LoadDex("StaticsFromCode");
260  const DexFile* dex_file = Runtime::Current()->GetCompileTimeClassPath(class_loader)[0];
261  CHECK(dex_file != NULL);
262
263  Class* klass =
264      class_linker_->FindClass("LStaticsFromCode;", soa.Decode<ClassLoader*>(class_loader));
265  ArtMethod* clinit = klass->FindDirectMethod("<clinit>", "()V");
266  const DexFile::StringId* klass_string_id = dex_file->FindStringId("LStaticsFromCode;");
267  ASSERT_TRUE(klass_string_id != NULL);
268  const DexFile::TypeId* klass_type_id = dex_file->FindTypeId(
269      dex_file->GetIndexForStringId(*klass_string_id));
270  ASSERT_TRUE(klass_type_id != NULL);
271
272  const DexFile::StringId* type_string_id = dex_file->FindStringId("Ljava/lang/Object;");
273  ASSERT_TRUE(type_string_id != NULL);
274  const DexFile::TypeId* type_type_id = dex_file->FindTypeId(
275      dex_file->GetIndexForStringId(*type_string_id));
276  ASSERT_TRUE(type_type_id != NULL);
277
278  const DexFile::StringId* name_str_id = dex_file->FindStringId("s0");
279  ASSERT_TRUE(name_str_id != NULL);
280
281  const DexFile::FieldId* field_id = dex_file->FindFieldId(
282      *klass_type_id, *name_str_id, *type_type_id);
283  ASSERT_TRUE(field_id != NULL);
284  uint32_t field_idx = dex_file->GetIndexForFieldId(*field_id);
285
286  ArtField* field = FindFieldFromCode(field_idx, clinit, Thread::Current(), StaticObjectRead,
287                                      sizeof(Object*), true);
288  Object* s0 = field->GetObj(klass);
289  EXPECT_TRUE(s0 != NULL);
290
291  SirtRef<CharArray> char_array(soa.Self(), CharArray::Alloc(soa.Self(), 0));
292  field->SetObj(field->GetDeclaringClass(), char_array.get());
293  EXPECT_EQ(char_array.get(), field->GetObj(klass));
294
295  field->SetObj(field->GetDeclaringClass(), NULL);
296  EXPECT_EQ(NULL, field->GetObj(klass));
297
298  // TODO: more exhaustive tests of all 6 cases of ArtField::*FromCode
299}
300
301TEST_F(ObjectTest, String) {
302  ScopedObjectAccess soa(Thread::Current());
303  // Test the empty string.
304  AssertString(0, "",     "", 0);
305
306  // Test one-byte characters.
307  AssertString(1, " ",    "\x00\x20",         0x20);
308  AssertString(1, "",     "\x00\x00",         0);
309  AssertString(1, "\x7f", "\x00\x7f",         0x7f);
310  AssertString(2, "hi",   "\x00\x68\x00\x69", (31 * 0x68) + 0x69);
311
312  // Test two-byte characters.
313  AssertString(1, "\xc2\x80",   "\x00\x80",                 0x80);
314  AssertString(1, "\xd9\xa6",   "\x06\x66",                 0x0666);
315  AssertString(1, "\xdf\xbf",   "\x07\xff",                 0x07ff);
316  AssertString(3, "h\xd9\xa6i", "\x00\x68\x06\x66\x00\x69", (31 * ((31 * 0x68) + 0x0666)) + 0x69);
317
318  // Test three-byte characters.
319  AssertString(1, "\xe0\xa0\x80",   "\x08\x00",                 0x0800);
320  AssertString(1, "\xe1\x88\xb4",   "\x12\x34",                 0x1234);
321  AssertString(1, "\xef\xbf\xbf",   "\xff\xff",                 0xffff);
322  AssertString(3, "h\xe1\x88\xb4i", "\x00\x68\x12\x34\x00\x69", (31 * ((31 * 0x68) + 0x1234)) + 0x69);
323}
324
325TEST_F(ObjectTest, StringEqualsUtf8) {
326  ScopedObjectAccess soa(Thread::Current());
327  SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
328  EXPECT_TRUE(string->Equals("android"));
329  EXPECT_FALSE(string->Equals("Android"));
330  EXPECT_FALSE(string->Equals("ANDROID"));
331  EXPECT_FALSE(string->Equals(""));
332  EXPECT_FALSE(string->Equals("and"));
333  EXPECT_FALSE(string->Equals("androids"));
334
335  SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
336  EXPECT_TRUE(empty->Equals(""));
337  EXPECT_FALSE(empty->Equals("a"));
338}
339
340TEST_F(ObjectTest, StringEquals) {
341  ScopedObjectAccess soa(Thread::Current());
342  SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
343  SirtRef<String> string_2(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
344  EXPECT_TRUE(string->Equals(string_2.get()));
345  EXPECT_FALSE(string->Equals("Android"));
346  EXPECT_FALSE(string->Equals("ANDROID"));
347  EXPECT_FALSE(string->Equals(""));
348  EXPECT_FALSE(string->Equals("and"));
349  EXPECT_FALSE(string->Equals("androids"));
350
351  SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
352  EXPECT_TRUE(empty->Equals(""));
353  EXPECT_FALSE(empty->Equals("a"));
354}
355
356TEST_F(ObjectTest, StringCompareTo) {
357  ScopedObjectAccess soa(Thread::Current());
358  SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
359  SirtRef<String> string_2(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
360  SirtRef<String> string_3(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "Android"));
361  SirtRef<String> string_4(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "and"));
362  SirtRef<String> string_5(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
363  EXPECT_EQ(0, string->CompareTo(string_2.get()));
364  EXPECT_LT(0, string->CompareTo(string_3.get()));
365  EXPECT_GT(0, string_3->CompareTo(string.get()));
366  EXPECT_LT(0, string->CompareTo(string_4.get()));
367  EXPECT_GT(0, string_4->CompareTo(string.get()));
368  EXPECT_LT(0, string->CompareTo(string_5.get()));
369  EXPECT_GT(0, string_5->CompareTo(string.get()));
370}
371
372TEST_F(ObjectTest, StringLength) {
373  ScopedObjectAccess soa(Thread::Current());
374  SirtRef<String> string(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "android"));
375  EXPECT_EQ(string->GetLength(), 7);
376  EXPECT_EQ(string->GetUtfLength(), 7);
377
378  string->SetOffset(2);
379  string->SetCount(5);
380  EXPECT_TRUE(string->Equals("droid"));
381  EXPECT_EQ(string->GetLength(), 5);
382  EXPECT_EQ(string->GetUtfLength(), 5);
383}
384
385TEST_F(ObjectTest, DescriptorCompare) {
386  ScopedObjectAccess soa(Thread::Current());
387  ClassLinker* linker = class_linker_;
388
389  jobject jclass_loader_1 = LoadDex("ProtoCompare");
390  jobject jclass_loader_2 = LoadDex("ProtoCompare2");
391  SirtRef<ClassLoader> class_loader_1(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader_1));
392  SirtRef<ClassLoader> class_loader_2(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader_2));
393
394  Class* klass1 = linker->FindClass("LProtoCompare;", class_loader_1.get());
395  ASSERT_TRUE(klass1 != NULL);
396  Class* klass2 = linker->FindClass("LProtoCompare2;", class_loader_2.get());
397  ASSERT_TRUE(klass2 != NULL);
398
399  ArtMethod* m1_1 = klass1->GetVirtualMethod(0);
400  MethodHelper mh(m1_1);
401  EXPECT_STREQ(mh.GetName(), "m1");
402  ArtMethod* m2_1 = klass1->GetVirtualMethod(1);
403  mh.ChangeMethod(m2_1);
404  EXPECT_STREQ(mh.GetName(), "m2");
405  ArtMethod* m3_1 = klass1->GetVirtualMethod(2);
406  mh.ChangeMethod(m3_1);
407  EXPECT_STREQ(mh.GetName(), "m3");
408  ArtMethod* m4_1 = klass1->GetVirtualMethod(3);
409  mh.ChangeMethod(m4_1);
410  EXPECT_STREQ(mh.GetName(), "m4");
411
412  ArtMethod* m1_2 = klass2->GetVirtualMethod(0);
413  mh.ChangeMethod(m1_2);
414  EXPECT_STREQ(mh.GetName(), "m1");
415  ArtMethod* m2_2 = klass2->GetVirtualMethod(1);
416  mh.ChangeMethod(m2_2);
417  EXPECT_STREQ(mh.GetName(), "m2");
418  ArtMethod* m3_2 = klass2->GetVirtualMethod(2);
419  mh.ChangeMethod(m3_2);
420  EXPECT_STREQ(mh.GetName(), "m3");
421  ArtMethod* m4_2 = klass2->GetVirtualMethod(3);
422  mh.ChangeMethod(m4_2);
423  EXPECT_STREQ(mh.GetName(), "m4");
424
425  mh.ChangeMethod(m1_1);
426  MethodHelper mh2(m1_2);
427  EXPECT_TRUE(mh.HasSameNameAndSignature(&mh2));
428  EXPECT_TRUE(mh2.HasSameNameAndSignature(&mh));
429
430  mh.ChangeMethod(m2_1);
431  mh2.ChangeMethod(m2_2);
432  EXPECT_TRUE(mh.HasSameNameAndSignature(&mh2));
433  EXPECT_TRUE(mh2.HasSameNameAndSignature(&mh));
434
435  mh.ChangeMethod(m3_1);
436  mh2.ChangeMethod(m3_2);
437  EXPECT_TRUE(mh.HasSameNameAndSignature(&mh2));
438  EXPECT_TRUE(mh2.HasSameNameAndSignature(&mh));
439
440  mh.ChangeMethod(m4_1);
441  mh2.ChangeMethod(m4_2);
442  EXPECT_TRUE(mh.HasSameNameAndSignature(&mh2));
443  EXPECT_TRUE(mh2.HasSameNameAndSignature(&mh));
444}
445
446TEST_F(ObjectTest, StringHashCode) {
447  ScopedObjectAccess soa(Thread::Current());
448  SirtRef<String> empty(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
449  SirtRef<String> A(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "A"));
450  SirtRef<String> ABC(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "ABC"));
451
452  EXPECT_EQ(0, empty->GetHashCode());
453  EXPECT_EQ(65, A->GetHashCode());
454  EXPECT_EQ(64578, ABC->GetHashCode());
455}
456
457TEST_F(ObjectTest, InstanceOf) {
458  ScopedObjectAccess soa(Thread::Current());
459  jobject jclass_loader = LoadDex("XandY");
460  SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
461
462  Class* X = class_linker_->FindClass("LX;", class_loader.get());
463  Class* Y = class_linker_->FindClass("LY;", class_loader.get());
464  ASSERT_TRUE(X != NULL);
465  ASSERT_TRUE(Y != NULL);
466
467  SirtRef<Object> x(soa.Self(), X->AllocObject(soa.Self()));
468  SirtRef<Object> y(soa.Self(), Y->AllocObject(soa.Self()));
469  ASSERT_TRUE(x.get() != NULL);
470  ASSERT_TRUE(y.get() != NULL);
471
472  EXPECT_TRUE(x->InstanceOf(X));
473  EXPECT_FALSE(x->InstanceOf(Y));
474  EXPECT_TRUE(y->InstanceOf(X));
475  EXPECT_TRUE(y->InstanceOf(Y));
476
477  Class* java_lang_Class = class_linker_->FindSystemClass("Ljava/lang/Class;");
478  Class* Object_array_class = class_linker_->FindSystemClass("[Ljava/lang/Object;");
479
480  EXPECT_FALSE(java_lang_Class->InstanceOf(Object_array_class));
481  EXPECT_TRUE(Object_array_class->InstanceOf(java_lang_Class));
482
483  // All array classes implement Cloneable and Serializable.
484  Object* array = ObjectArray<Object>::Alloc(soa.Self(), Object_array_class, 1);
485  Class* java_lang_Cloneable = class_linker_->FindSystemClass("Ljava/lang/Cloneable;");
486  Class* java_io_Serializable = class_linker_->FindSystemClass("Ljava/io/Serializable;");
487  EXPECT_TRUE(array->InstanceOf(java_lang_Cloneable));
488  EXPECT_TRUE(array->InstanceOf(java_io_Serializable));
489}
490
491TEST_F(ObjectTest, IsAssignableFrom) {
492  ScopedObjectAccess soa(Thread::Current());
493  jobject jclass_loader = LoadDex("XandY");
494  SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
495  Class* X = class_linker_->FindClass("LX;", class_loader.get());
496  Class* Y = class_linker_->FindClass("LY;", class_loader.get());
497
498  EXPECT_TRUE(X->IsAssignableFrom(X));
499  EXPECT_TRUE(X->IsAssignableFrom(Y));
500  EXPECT_FALSE(Y->IsAssignableFrom(X));
501  EXPECT_TRUE(Y->IsAssignableFrom(Y));
502
503  // class final String implements CharSequence, ..
504  Class* string = class_linker_->FindSystemClass("Ljava/lang/String;");
505  Class* charseq = class_linker_->FindSystemClass("Ljava/lang/CharSequence;");
506  // Can String be assigned to CharSequence without a cast?
507  EXPECT_TRUE(charseq->IsAssignableFrom(string));
508  // Can CharSequence be assigned to String without a cast?
509  EXPECT_FALSE(string->IsAssignableFrom(charseq));
510
511  // Primitive types are only assignable to themselves
512  const char* prims = "ZBCSIJFD";
513  Class* prim_types[strlen(prims)];
514  for (size_t i = 0; i < strlen(prims); i++) {
515    prim_types[i] = class_linker_->FindPrimitiveClass(prims[i]);
516  }
517  for (size_t i = 0; i < strlen(prims); i++) {
518    for (size_t j = 0; i < strlen(prims); i++) {
519      if (i == j) {
520        EXPECT_TRUE(prim_types[i]->IsAssignableFrom(prim_types[j]));
521      } else {
522        EXPECT_FALSE(prim_types[i]->IsAssignableFrom(prim_types[j]));
523      }
524    }
525  }
526}
527
528TEST_F(ObjectTest, IsAssignableFromArray) {
529  ScopedObjectAccess soa(Thread::Current());
530  jobject jclass_loader = LoadDex("XandY");
531  SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
532  Class* X = class_linker_->FindClass("LX;", class_loader.get());
533  Class* Y = class_linker_->FindClass("LY;", class_loader.get());
534  ASSERT_TRUE(X != NULL);
535  ASSERT_TRUE(Y != NULL);
536
537  Class* YA = class_linker_->FindClass("[LY;", class_loader.get());
538  Class* YAA = class_linker_->FindClass("[[LY;", class_loader.get());
539  ASSERT_TRUE(YA != NULL);
540  ASSERT_TRUE(YAA != NULL);
541
542  Class* XAA = class_linker_->FindClass("[[LX;", class_loader.get());
543  ASSERT_TRUE(XAA != NULL);
544
545  Class* O = class_linker_->FindSystemClass("Ljava/lang/Object;");
546  Class* OA = class_linker_->FindSystemClass("[Ljava/lang/Object;");
547  Class* OAA = class_linker_->FindSystemClass("[[Ljava/lang/Object;");
548  Class* OAAA = class_linker_->FindSystemClass("[[[Ljava/lang/Object;");
549  ASSERT_TRUE(O != NULL);
550  ASSERT_TRUE(OA != NULL);
551  ASSERT_TRUE(OAA != NULL);
552  ASSERT_TRUE(OAAA != NULL);
553
554  Class* S = class_linker_->FindSystemClass("Ljava/io/Serializable;");
555  Class* SA = class_linker_->FindSystemClass("[Ljava/io/Serializable;");
556  Class* SAA = class_linker_->FindSystemClass("[[Ljava/io/Serializable;");
557  ASSERT_TRUE(S != NULL);
558  ASSERT_TRUE(SA != NULL);
559  ASSERT_TRUE(SAA != NULL);
560
561  Class* IA = class_linker_->FindSystemClass("[I");
562  ASSERT_TRUE(IA != NULL);
563
564  EXPECT_TRUE(YAA->IsAssignableFrom(YAA));  // identity
565  EXPECT_TRUE(XAA->IsAssignableFrom(YAA));  // element superclass
566  EXPECT_FALSE(YAA->IsAssignableFrom(XAA));
567  EXPECT_FALSE(Y->IsAssignableFrom(YAA));
568  EXPECT_FALSE(YA->IsAssignableFrom(YAA));
569  EXPECT_TRUE(O->IsAssignableFrom(YAA));  // everything is an Object
570  EXPECT_TRUE(OA->IsAssignableFrom(YAA));
571  EXPECT_TRUE(OAA->IsAssignableFrom(YAA));
572  EXPECT_TRUE(S->IsAssignableFrom(YAA));  // all arrays are Serializable
573  EXPECT_TRUE(SA->IsAssignableFrom(YAA));
574  EXPECT_FALSE(SAA->IsAssignableFrom(YAA));  // unless Y was Serializable
575
576  EXPECT_FALSE(IA->IsAssignableFrom(OA));
577  EXPECT_FALSE(OA->IsAssignableFrom(IA));
578  EXPECT_TRUE(O->IsAssignableFrom(IA));
579}
580
581TEST_F(ObjectTest, FindInstanceField) {
582  ScopedObjectAccess soa(Thread::Current());
583  SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "ABC"));
584  ASSERT_TRUE(s.get() != NULL);
585  Class* c = s->GetClass();
586  ASSERT_TRUE(c != NULL);
587
588  // Wrong type.
589  EXPECT_TRUE(c->FindDeclaredInstanceField("count", "J") == NULL);
590  EXPECT_TRUE(c->FindInstanceField("count", "J") == NULL);
591
592  // Wrong name.
593  EXPECT_TRUE(c->FindDeclaredInstanceField("Count", "I") == NULL);
594  EXPECT_TRUE(c->FindInstanceField("Count", "I") == NULL);
595
596  // Right name and type.
597  ArtField* f1 = c->FindDeclaredInstanceField("count", "I");
598  ArtField* f2 = c->FindInstanceField("count", "I");
599  EXPECT_TRUE(f1 != NULL);
600  EXPECT_TRUE(f2 != NULL);
601  EXPECT_EQ(f1, f2);
602
603  // TODO: check that s.count == 3.
604
605  // Ensure that we handle superclass fields correctly...
606  c = class_linker_->FindSystemClass("Ljava/lang/StringBuilder;");
607  ASSERT_TRUE(c != NULL);
608  // No StringBuilder.count...
609  EXPECT_TRUE(c->FindDeclaredInstanceField("count", "I") == NULL);
610  // ...but there is an AbstractStringBuilder.count.
611  EXPECT_TRUE(c->FindInstanceField("count", "I") != NULL);
612}
613
614TEST_F(ObjectTest, FindStaticField) {
615  ScopedObjectAccess soa(Thread::Current());
616  SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "ABC"));
617  ASSERT_TRUE(s.get() != NULL);
618  Class* c = s->GetClass();
619  ASSERT_TRUE(c != NULL);
620
621  // Wrong type.
622  EXPECT_TRUE(c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "I") == NULL);
623  EXPECT_TRUE(c->FindStaticField("CASE_INSENSITIVE_ORDER", "I") == NULL);
624
625  // Wrong name.
626  EXPECT_TRUE(c->FindDeclaredStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == NULL);
627  EXPECT_TRUE(c->FindStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == NULL);
628
629  // Right name and type.
630  ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
631  ArtField* f2 = c->FindStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
632  EXPECT_TRUE(f1 != NULL);
633  EXPECT_TRUE(f2 != NULL);
634  EXPECT_EQ(f1, f2);
635
636  // TODO: test static fields via superclasses.
637  // TODO: test static fields via interfaces.
638  // TODO: test that interfaces trump superclasses.
639}
640
641}  // namespace mirror
642}  // namespace art
643