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