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-alloc-inl.h" 24 #include "array-inl.h" 25 #include "art_field-inl.h" 26 #include "art_method-inl.h" 27 #include "asm_support.h" 28 #include "base/enums.h" 29 #include "class-alloc-inl.h" 30 #include "class-inl.h" 31 #include "class_linker-inl.h" 32 #include "class_linker.h" 33 #include "class_root.h" 34 #include "common_runtime_test.h" 35 #include "dex/dex_file.h" 36 #include "entrypoints/entrypoint_utils-inl.h" 37 #include "gc/accounting/card_table-inl.h" 38 #include "gc/heap.h" 39 #include "handle_scope-inl.h" 40 #include "iftable-inl.h" 41 #include "obj_ptr.h" 42 #include "object-inl.h" 43 #include "object_array-alloc-inl.h" 44 #include "object_array-inl.h" 45 #include "scoped_thread_state_change-inl.h" 46 #include "string-inl.h" 47 48 namespace art { 49 namespace mirror { 50 51 class ObjectTest : public CommonRuntimeTest { 52 protected: 53 void AssertString(int32_t expected_utf16_length, 54 const char* utf8_in, 55 const char* utf16_expected_le, 56 int32_t expected_hash) 57 REQUIRES_SHARED(Locks::mutator_lock_) { 58 std::unique_ptr<uint16_t[]> utf16_expected(new uint16_t[expected_utf16_length]); 59 for (int32_t i = 0; i < expected_utf16_length; i++) { 60 uint16_t ch = (((utf16_expected_le[i*2 + 0] & 0xff) << 8) | 61 ((utf16_expected_le[i*2 + 1] & 0xff) << 0)); 62 utf16_expected[i] = ch; 63 } 64 65 Thread* self = Thread::Current(); 66 StackHandleScope<1> hs(self); 67 Handle<String> string( 68 hs.NewHandle(String::AllocFromModifiedUtf8(self, expected_utf16_length, utf8_in))); 69 ASSERT_EQ(expected_utf16_length, string->GetLength()); 70 ASSERT_EQ(string->IsValueNull(), false); 71 // strlen is necessary because the 1-character string "\x00\x00" is interpreted as "" 72 ASSERT_TRUE(string->Equals(utf8_in) || (expected_utf16_length == 1 && strlen(utf8_in) == 0)); 73 for (int32_t i = 0; i < expected_utf16_length; i++) { 74 EXPECT_EQ(utf16_expected[i], string->CharAt(i)); 75 } 76 EXPECT_EQ(expected_hash, string->GetHashCode()); 77 } 78 79 template <class T> 80 ObjPtr<mirror::ObjectArray<T>> AllocObjectArray(Thread* self, size_t length) 81 REQUIRES_SHARED(Locks::mutator_lock_) { 82 return mirror::ObjectArray<T>::Alloc( 83 self, GetClassRoot(ClassRoot::kObjectArrayClass, class_linker_), length); 84 } 85 }; 86 87 // Keep constants in sync. 88 TEST_F(ObjectTest, Constants) { 89 EXPECT_EQ(kObjectReferenceSize, sizeof(HeapReference<Object>)); 90 EXPECT_EQ(kObjectHeaderSize, sizeof(Object)); 91 EXPECT_EQ(ART_METHOD_QUICK_CODE_OFFSET_32, 92 ArtMethod::EntryPointFromQuickCompiledCodeOffset(PointerSize::k32). 93 Int32Value()); 94 EXPECT_EQ(ART_METHOD_QUICK_CODE_OFFSET_64, 95 ArtMethod::EntryPointFromQuickCompiledCodeOffset(PointerSize::k64). 96 Int32Value()); 97 } 98 99 TEST_F(ObjectTest, IsInSamePackage) { 100 // Matches 101 EXPECT_TRUE(Class::IsInSamePackage("Ljava/lang/Object;", "Ljava/lang/Class;")); 102 EXPECT_TRUE(Class::IsInSamePackage("LFoo;", "LBar;")); 103 104 // Mismatches 105 EXPECT_FALSE(Class::IsInSamePackage("Ljava/lang/Object;", "Ljava/io/File;")); 106 EXPECT_FALSE(Class::IsInSamePackage("Ljava/lang/Object;", "Ljava/lang/reflect/Method;")); 107 } 108 109 TEST_F(ObjectTest, Clone) { 110 ScopedObjectAccess soa(Thread::Current()); 111 StackHandleScope<2> hs(soa.Self()); 112 Handle<ObjectArray<Object>> a1(hs.NewHandle(AllocObjectArray<Object>(soa.Self(), 256))); 113 size_t s1 = a1->SizeOf(); 114 ObjPtr<Object> clone = a1->Clone(soa.Self()); 115 EXPECT_EQ(s1, clone->SizeOf()); 116 EXPECT_TRUE(clone->GetClass() == a1->GetClass()); 117 } 118 119 TEST_F(ObjectTest, AllocObjectArray) { 120 ScopedObjectAccess soa(Thread::Current()); 121 StackHandleScope<3> hs(soa.Self()); 122 Handle<ObjectArray<Object>> oa(hs.NewHandle(AllocObjectArray<Object>(soa.Self(), 2))); 123 EXPECT_EQ(2, oa->GetLength()); 124 EXPECT_TRUE(oa->Get(0) == nullptr); 125 EXPECT_TRUE(oa->Get(1) == nullptr); 126 oa->Set<false>(0, oa.Get()); 127 EXPECT_TRUE(oa->Get(0) == oa.Get()); 128 EXPECT_TRUE(oa->Get(1) == nullptr); 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 Handle<Class> aioobe = hs.NewHandle( 134 class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;")); 135 136 EXPECT_TRUE(oa->Get(-1) == nullptr); 137 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 138 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 139 soa.Self()->ClearException(); 140 141 EXPECT_TRUE(oa->Get(2) == nullptr); 142 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 143 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 144 soa.Self()->ClearException(); 145 146 ASSERT_TRUE(oa->GetClass() != nullptr); 147 Handle<mirror::Class> klass(hs.NewHandle(oa->GetClass())); 148 ASSERT_EQ(2U, klass->NumDirectInterfaces()); 149 EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;"), 150 mirror::Class::GetDirectInterface(soa.Self(), klass.Get(), 0)); 151 EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;"), 152 mirror::Class::GetDirectInterface(soa.Self(), klass.Get(), 1)); 153 } 154 155 TEST_F(ObjectTest, AllocArray) { 156 ScopedObjectAccess soa(Thread::Current()); 157 StackHandleScope<2> hs(soa.Self()); 158 MutableHandle<Class> c = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[I")); 159 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); 160 MutableHandle<Array> a = hs.NewHandle( 161 Array::Alloc<true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type)); 162 EXPECT_TRUE(c.Get() == a->GetClass()); 163 EXPECT_EQ(1, a->GetLength()); 164 165 c.Assign(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")); 166 a.Assign(Array::Alloc<true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type)); 167 EXPECT_TRUE(c.Get() == a->GetClass()); 168 EXPECT_EQ(1, a->GetLength()); 169 170 c.Assign(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;")); 171 a.Assign(Array::Alloc<true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type)); 172 EXPECT_TRUE(c.Get() == a->GetClass()); 173 EXPECT_EQ(1, a->GetLength()); 174 } 175 176 TEST_F(ObjectTest, AllocArray_FillUsable) { 177 ScopedObjectAccess soa(Thread::Current()); 178 StackHandleScope<2> hs(soa.Self()); 179 MutableHandle<Class> c = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[B")); 180 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); 181 MutableHandle<Array> a = hs.NewHandle( 182 Array::Alloc<true, true>(soa.Self(), c.Get(), 1, c->GetComponentSizeShift(), allocator_type)); 183 EXPECT_TRUE(c.Get() == a->GetClass()); 184 EXPECT_LE(1, a->GetLength()); 185 186 c.Assign(class_linker_->FindSystemClass(soa.Self(), "[I")); 187 a.Assign( 188 Array::Alloc<true, true>(soa.Self(), c.Get(), 2, c->GetComponentSizeShift(), allocator_type)); 189 EXPECT_TRUE(c.Get() == a->GetClass()); 190 EXPECT_LE(2, a->GetLength()); 191 192 c.Assign(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")); 193 a.Assign( 194 Array::Alloc<true, true>(soa.Self(), c.Get(), 2, c->GetComponentSizeShift(), allocator_type)); 195 EXPECT_TRUE(c.Get() == a->GetClass()); 196 EXPECT_LE(2, a->GetLength()); 197 198 c.Assign(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;")); 199 a.Assign( 200 Array::Alloc<true, true>(soa.Self(), c.Get(), 2, c->GetComponentSizeShift(), allocator_type)); 201 EXPECT_TRUE(c.Get() == a->GetClass()); 202 EXPECT_LE(2, a->GetLength()); 203 } 204 205 template<typename ArrayT> 206 void TestPrimitiveArray(ClassLinker* cl) { 207 ScopedObjectAccess soa(Thread::Current()); 208 using T = typename ArrayT::ElementType; 209 210 StackHandleScope<2> hs(soa.Self()); 211 Handle<ArrayT> a = hs.NewHandle(ArrayT::Alloc(soa.Self(), 2)); 212 EXPECT_EQ(2, a->GetLength()); 213 EXPECT_EQ(0, a->Get(0)); 214 EXPECT_EQ(0, a->Get(1)); 215 a->Set(0, T(123)); 216 EXPECT_EQ(T(123), a->Get(0)); 217 EXPECT_EQ(0, a->Get(1)); 218 a->Set(1, T(321)); 219 EXPECT_EQ(T(123), a->Get(0)); 220 EXPECT_EQ(T(321), a->Get(1)); 221 222 Handle<Class> aioobe = hs.NewHandle( 223 cl->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;")); 224 225 EXPECT_EQ(0, a->Get(-1)); 226 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 227 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 228 soa.Self()->ClearException(); 229 230 EXPECT_EQ(0, a->Get(2)); 231 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 232 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 233 soa.Self()->ClearException(); 234 } 235 236 TEST_F(ObjectTest, PrimitiveArray_Boolean_Alloc) { 237 TestPrimitiveArray<BooleanArray>(class_linker_); 238 } 239 TEST_F(ObjectTest, PrimitiveArray_Byte_Alloc) { 240 TestPrimitiveArray<ByteArray>(class_linker_); 241 } 242 TEST_F(ObjectTest, PrimitiveArray_Char_Alloc) { 243 TestPrimitiveArray<CharArray>(class_linker_); 244 } 245 TEST_F(ObjectTest, PrimitiveArray_Int_Alloc) { 246 TestPrimitiveArray<IntArray>(class_linker_); 247 } 248 TEST_F(ObjectTest, PrimitiveArray_Long_Alloc) { 249 TestPrimitiveArray<LongArray>(class_linker_); 250 } 251 TEST_F(ObjectTest, PrimitiveArray_Short_Alloc) { 252 TestPrimitiveArray<ShortArray>(class_linker_); 253 } 254 255 TEST_F(ObjectTest, PrimitiveArray_Double_Alloc) { 256 using ArrayT = DoubleArray; 257 ScopedObjectAccess soa(Thread::Current()); 258 using T = typename ArrayT::ElementType; 259 260 StackHandleScope<2> hs(soa.Self()); 261 Handle<ArrayT> a = hs.NewHandle(ArrayT::Alloc(soa.Self(), 2)); 262 EXPECT_EQ(2, a->GetLength()); 263 EXPECT_DOUBLE_EQ(0, a->Get(0)); 264 EXPECT_DOUBLE_EQ(0, a->Get(1)); 265 a->Set(0, T(123)); 266 EXPECT_DOUBLE_EQ(T(123), a->Get(0)); 267 EXPECT_DOUBLE_EQ(0, a->Get(1)); 268 a->Set(1, T(321)); 269 EXPECT_DOUBLE_EQ(T(123), a->Get(0)); 270 EXPECT_DOUBLE_EQ(T(321), a->Get(1)); 271 272 Handle<Class> aioobe = hs.NewHandle( 273 class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;")); 274 275 EXPECT_DOUBLE_EQ(0, a->Get(-1)); 276 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 277 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 278 soa.Self()->ClearException(); 279 280 EXPECT_DOUBLE_EQ(0, a->Get(2)); 281 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 282 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 283 soa.Self()->ClearException(); 284 } 285 286 TEST_F(ObjectTest, PrimitiveArray_Float_Alloc) { 287 using ArrayT = FloatArray; 288 ScopedObjectAccess soa(Thread::Current()); 289 using T = typename ArrayT::ElementType; 290 291 StackHandleScope<2> hs(soa.Self()); 292 Handle<ArrayT> a = hs.NewHandle(ArrayT::Alloc(soa.Self(), 2)); 293 EXPECT_FLOAT_EQ(2, a->GetLength()); 294 EXPECT_FLOAT_EQ(0, a->Get(0)); 295 EXPECT_FLOAT_EQ(0, a->Get(1)); 296 a->Set(0, T(123)); 297 EXPECT_FLOAT_EQ(T(123), a->Get(0)); 298 EXPECT_FLOAT_EQ(0, a->Get(1)); 299 a->Set(1, T(321)); 300 EXPECT_FLOAT_EQ(T(123), a->Get(0)); 301 EXPECT_FLOAT_EQ(T(321), a->Get(1)); 302 303 Handle<Class> aioobe = hs.NewHandle( 304 class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/ArrayIndexOutOfBoundsException;")); 305 306 EXPECT_FLOAT_EQ(0, a->Get(-1)); 307 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 308 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 309 soa.Self()->ClearException(); 310 311 EXPECT_FLOAT_EQ(0, a->Get(2)); 312 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 313 EXPECT_OBJ_PTR_EQ(aioobe.Get(), soa.Self()->GetException()->GetClass()); 314 soa.Self()->ClearException(); 315 } 316 317 318 TEST_F(ObjectTest, CreateMultiArray) { 319 ScopedObjectAccess soa(Thread::Current()); 320 321 StackHandleScope<4> hs(soa.Self()); 322 Handle<Class> int_class(hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "I"))); 323 Handle<Class> int_array_class = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[I")); 324 MutableHandle<IntArray> dims(hs.NewHandle(IntArray::Alloc(soa.Self(), 1))); 325 dims->Set<false>(0, 1); 326 MutableHandle<Array> multi = hs.NewHandle(Array::CreateMultiArray(soa.Self(), int_class, dims)); 327 EXPECT_OBJ_PTR_EQ(int_array_class.Get(), multi->GetClass()); 328 EXPECT_EQ(1, multi->GetLength()); 329 330 dims->Set<false>(0, -1); 331 multi.Assign(Array::CreateMultiArray(soa.Self(), int_class, dims)); 332 EXPECT_TRUE(soa.Self()->IsExceptionPending()); 333 EXPECT_EQ(mirror::Class::PrettyDescriptor(soa.Self()->GetException()->GetClass()), 334 "java.lang.NegativeArraySizeException"); 335 soa.Self()->ClearException(); 336 337 dims.Assign(IntArray::Alloc(soa.Self(), 2)); 338 for (int i = 1; i < 20; ++i) { 339 for (int j = 0; j < 20; ++j) { 340 dims->Set<false>(0, i); 341 dims->Set<false>(1, j); 342 multi.Assign(Array::CreateMultiArray(soa.Self(), int_class, dims)); 343 ObjPtr<mirror::Class> expected_class = class_linker_->FindSystemClass(soa.Self(), "[[I"); 344 EXPECT_OBJ_PTR_EQ(multi->GetClass(), expected_class); 345 EXPECT_EQ(i, multi->GetLength()); 346 for (int k = 0; k < i; ++k) { 347 ObjPtr<Array> outer = multi->AsObjectArray<Array>()->Get(k); 348 EXPECT_OBJ_PTR_EQ(int_array_class.Get(), outer->GetClass()); 349 EXPECT_EQ(j, outer->GetLength()); 350 } 351 } 352 } 353 } 354 355 TEST_F(ObjectTest, StaticFieldFromCode) { 356 // pretend we are trying to access 'Static.s0' from StaticsFromCode.<clinit> 357 ScopedObjectAccess soa(Thread::Current()); 358 jobject class_loader = LoadDex("StaticsFromCode"); 359 const DexFile* dex_file = GetFirstDexFile(class_loader); 360 361 StackHandleScope<3> hs(soa.Self()); 362 Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<ClassLoader>(class_loader))); 363 Handle<Class> klass = 364 hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", loader)); 365 ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize); 366 const dex::TypeId* klass_type_id = dex_file->FindTypeId("LStaticsFromCode;"); 367 ASSERT_TRUE(klass_type_id != nullptr); 368 369 const dex::TypeId* type_type_id = dex_file->FindTypeId("Ljava/lang/Object;"); 370 ASSERT_TRUE(type_type_id != nullptr); 371 372 const dex::StringId* name_str_id = dex_file->FindStringId("s0"); 373 ASSERT_TRUE(name_str_id != nullptr); 374 375 const dex::FieldId* field_id = dex_file->FindFieldId( 376 *klass_type_id, *name_str_id, *type_type_id); 377 ASSERT_TRUE(field_id != nullptr); 378 uint32_t field_idx = dex_file->GetIndexForFieldId(*field_id); 379 380 ArtField* field = FindFieldFromCode<StaticObjectRead, true>(field_idx, clinit, Thread::Current(), 381 sizeof(HeapReference<Object>)); 382 ObjPtr<Object> s0 = field->GetObj(klass.Get()); 383 EXPECT_TRUE(s0 != nullptr); 384 385 Handle<CharArray> char_array(hs.NewHandle(CharArray::Alloc(soa.Self(), 0))); 386 field->SetObj<false>(field->GetDeclaringClass(), char_array.Get()); 387 EXPECT_OBJ_PTR_EQ(char_array.Get(), field->GetObj(klass.Get())); 388 389 field->SetObj<false>(field->GetDeclaringClass(), nullptr); 390 EXPECT_EQ(nullptr, field->GetObj(klass.Get())); 391 392 // TODO: more exhaustive tests of all 6 cases of ArtField::*FromCode 393 } 394 395 TEST_F(ObjectTest, String) { 396 ScopedObjectAccess soa(Thread::Current()); 397 // Test the empty string. 398 AssertString(0, "", "", 0); 399 400 // Test one-byte characters. 401 AssertString(1, " ", "\x00\x20", 0x20); 402 AssertString(1, "", "\x00\x00", 0); 403 AssertString(1, "\x7f", "\x00\x7f", 0x7f); 404 AssertString(2, "hi", "\x00\x68\x00\x69", (31 * 0x68) + 0x69); 405 406 // Test two-byte characters. 407 AssertString(1, "\xc2\x80", "\x00\x80", 0x80); 408 AssertString(1, "\xd9\xa6", "\x06\x66", 0x0666); 409 AssertString(1, "\xdf\xbf", "\x07\xff", 0x07ff); 410 AssertString(3, "h\xd9\xa6i", "\x00\x68\x06\x66\x00\x69", 411 (31 * ((31 * 0x68) + 0x0666)) + 0x69); 412 413 // Test three-byte characters. 414 AssertString(1, "\xe0\xa0\x80", "\x08\x00", 0x0800); 415 AssertString(1, "\xe1\x88\xb4", "\x12\x34", 0x1234); 416 AssertString(1, "\xef\xbf\xbf", "\xff\xff", 0xffff); 417 AssertString(3, "h\xe1\x88\xb4i", "\x00\x68\x12\x34\x00\x69", 418 (31 * ((31 * 0x68) + 0x1234)) + 0x69); 419 420 // Test four-byte characters. 421 AssertString(2, "\xf0\x9f\x8f\xa0", "\xd8\x3c\xdf\xe0", (31 * 0xd83c) + 0xdfe0); 422 AssertString(2, "\xf0\x9f\x9a\x80", "\xd8\x3d\xde\x80", (31 * 0xd83d) + 0xde80); 423 AssertString(4, "h\xf0\x9f\x9a\x80i", "\x00\x68\xd8\x3d\xde\x80\x00\x69", 424 (31 * (31 * (31 * 0x68 + 0xd83d) + 0xde80) + 0x69)); 425 } 426 427 TEST_F(ObjectTest, StringEqualsUtf8) { 428 ScopedObjectAccess soa(Thread::Current()); 429 StackHandleScope<2> hs(soa.Self()); 430 Handle<String> string(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "android"))); 431 EXPECT_TRUE(string->Equals("android")); 432 EXPECT_FALSE(string->Equals("Android")); 433 EXPECT_FALSE(string->Equals("ANDROID")); 434 EXPECT_FALSE(string->Equals("")); 435 EXPECT_FALSE(string->Equals("and")); 436 EXPECT_FALSE(string->Equals("androids")); 437 438 Handle<String> empty(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), ""))); 439 EXPECT_TRUE(empty->Equals("")); 440 EXPECT_FALSE(empty->Equals("a")); 441 } 442 443 TEST_F(ObjectTest, StringEquals) { 444 ScopedObjectAccess soa(Thread::Current()); 445 StackHandleScope<3> hs(soa.Self()); 446 Handle<String> string(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "android"))); 447 Handle<String> string_2(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "android"))); 448 EXPECT_TRUE(string->Equals(string_2.Get())); 449 EXPECT_FALSE(string->Equals("Android")); 450 EXPECT_FALSE(string->Equals("ANDROID")); 451 EXPECT_FALSE(string->Equals("")); 452 EXPECT_FALSE(string->Equals("and")); 453 EXPECT_FALSE(string->Equals("androids")); 454 455 Handle<String> empty(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), ""))); 456 EXPECT_TRUE(empty->Equals("")); 457 EXPECT_FALSE(empty->Equals("a")); 458 } 459 460 TEST_F(ObjectTest, StringCompareTo) { 461 ScopedObjectAccess soa(Thread::Current()); 462 StackHandleScope<5> hs(soa.Self()); 463 Handle<String> string(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "android"))); 464 Handle<String> string_2(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "android"))); 465 Handle<String> string_3(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "Android"))); 466 Handle<String> string_4(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "and"))); 467 Handle<String> string_5(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), ""))); 468 EXPECT_EQ(0, string->CompareTo(string_2.Get())); 469 EXPECT_LT(0, string->CompareTo(string_3.Get())); 470 EXPECT_GT(0, string_3->CompareTo(string.Get())); 471 EXPECT_LT(0, string->CompareTo(string_4.Get())); 472 EXPECT_GT(0, string_4->CompareTo(string.Get())); 473 EXPECT_LT(0, string->CompareTo(string_5.Get())); 474 EXPECT_GT(0, string_5->CompareTo(string.Get())); 475 } 476 477 TEST_F(ObjectTest, StringLength) { 478 ScopedObjectAccess soa(Thread::Current()); 479 StackHandleScope<1> hs(soa.Self()); 480 Handle<String> string(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "android"))); 481 EXPECT_EQ(string->GetLength(), 7); 482 EXPECT_EQ(string->GetUtfLength(), 7); 483 } 484 485 TEST_F(ObjectTest, DescriptorCompare) { 486 // Two classloaders conflicts in compile_time_class_paths_. 487 ScopedObjectAccess soa(Thread::Current()); 488 ClassLinker* linker = class_linker_; 489 490 jobject jclass_loader_1 = LoadDex("ProtoCompare"); 491 jobject jclass_loader_2 = LoadDex("ProtoCompare2"); 492 StackHandleScope<4> hs(soa.Self()); 493 Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_1))); 494 Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_2))); 495 496 Handle<Class> klass1 = 497 hs.NewHandle(linker->FindClass(soa.Self(), "LProtoCompare;", class_loader_1)); 498 ASSERT_TRUE(klass1 != nullptr); 499 Handle<Class> klass2 = 500 hs.NewHandle(linker->FindClass(soa.Self(), "LProtoCompare2;", class_loader_2)); 501 ASSERT_TRUE(klass2 != nullptr); 502 503 ArtMethod* m1_1 = klass1->GetVirtualMethod(0, kRuntimePointerSize); 504 EXPECT_STREQ(m1_1->GetName(), "m1"); 505 ArtMethod* m2_1 = klass1->GetVirtualMethod(1, kRuntimePointerSize); 506 EXPECT_STREQ(m2_1->GetName(), "m2"); 507 ArtMethod* m3_1 = klass1->GetVirtualMethod(2, kRuntimePointerSize); 508 EXPECT_STREQ(m3_1->GetName(), "m3"); 509 ArtMethod* m4_1 = klass1->GetVirtualMethod(3, kRuntimePointerSize); 510 EXPECT_STREQ(m4_1->GetName(), "m4"); 511 512 ArtMethod* m1_2 = klass2->GetVirtualMethod(0, kRuntimePointerSize); 513 EXPECT_STREQ(m1_2->GetName(), "m1"); 514 ArtMethod* m2_2 = klass2->GetVirtualMethod(1, kRuntimePointerSize); 515 EXPECT_STREQ(m2_2->GetName(), "m2"); 516 ArtMethod* m3_2 = klass2->GetVirtualMethod(2, kRuntimePointerSize); 517 EXPECT_STREQ(m3_2->GetName(), "m3"); 518 ArtMethod* m4_2 = klass2->GetVirtualMethod(3, kRuntimePointerSize); 519 EXPECT_STREQ(m4_2->GetName(), "m4"); 520 } 521 522 TEST_F(ObjectTest, StringHashCode) { 523 ScopedObjectAccess soa(Thread::Current()); 524 StackHandleScope<3> hs(soa.Self()); 525 Handle<String> empty(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), ""))); 526 Handle<String> A(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "A"))); 527 Handle<String> ABC(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "ABC"))); 528 529 EXPECT_EQ(0, empty->GetHashCode()); 530 EXPECT_EQ(65, A->GetHashCode()); 531 EXPECT_EQ(64578, ABC->GetHashCode()); 532 } 533 534 TEST_F(ObjectTest, InstanceOf) { 535 ScopedObjectAccess soa(Thread::Current()); 536 jobject jclass_loader = LoadDex("XandY"); 537 StackHandleScope<10> hs(soa.Self()); 538 Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); 539 540 Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader)); 541 Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader)); 542 ASSERT_TRUE(X != nullptr); 543 ASSERT_TRUE(Y != nullptr); 544 545 Handle<Object> x(hs.NewHandle(X->AllocObject(soa.Self()))); 546 Handle<Object> y(hs.NewHandle(Y->AllocObject(soa.Self()))); 547 ASSERT_TRUE(x != nullptr); 548 ASSERT_TRUE(y != nullptr); 549 550 EXPECT_TRUE(x->InstanceOf(X.Get())); 551 EXPECT_FALSE(x->InstanceOf(Y.Get())); 552 EXPECT_TRUE(y->InstanceOf(X.Get())); 553 EXPECT_TRUE(y->InstanceOf(Y.Get())); 554 555 Handle<Class> java_lang_Class = 556 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Class;")); 557 Handle<Class> Object_array_class = 558 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")); 559 560 EXPECT_FALSE(java_lang_Class->InstanceOf(Object_array_class.Get())); 561 EXPECT_TRUE(Object_array_class->InstanceOf(java_lang_Class.Get())); 562 563 // All array classes implement Cloneable and Serializable. 564 Handle<Object> array = 565 hs.NewHandle<Object>(ObjectArray<Object>::Alloc(soa.Self(), Object_array_class.Get(), 1)); 566 Handle<Class> java_lang_Cloneable = 567 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Cloneable;")); 568 Handle<Class> java_io_Serializable = 569 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;")); 570 EXPECT_TRUE(array->InstanceOf(java_lang_Cloneable.Get())); 571 EXPECT_TRUE(array->InstanceOf(java_io_Serializable.Get())); 572 } 573 574 TEST_F(ObjectTest, IsAssignableFrom) { 575 ScopedObjectAccess soa(Thread::Current()); 576 jobject jclass_loader = LoadDex("XandY"); 577 StackHandleScope<5> hs(soa.Self()); 578 Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); 579 Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader)); 580 Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader)); 581 582 EXPECT_TRUE(X->IsAssignableFrom(X.Get())); 583 EXPECT_TRUE(X->IsAssignableFrom(Y.Get())); 584 EXPECT_FALSE(Y->IsAssignableFrom(X.Get())); 585 EXPECT_TRUE(Y->IsAssignableFrom(Y.Get())); 586 587 // class final String implements CharSequence, .. 588 Handle<Class> string = 589 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;")); 590 Handle<Class> charseq = 591 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/CharSequence;")); 592 // Can String be assigned to CharSequence without a cast? 593 EXPECT_TRUE(charseq->IsAssignableFrom(string.Get())); 594 // Can CharSequence be assigned to String without a cast? 595 EXPECT_FALSE(string->IsAssignableFrom(charseq.Get())); 596 597 // Primitive types are only assignable to themselves 598 const char* prims = "ZBCSIJFD"; 599 std::vector<ObjPtr<Class>> prim_types(strlen(prims)); 600 for (size_t i = 0; i < strlen(prims); i++) { 601 prim_types[i] = class_linker_->FindPrimitiveClass(prims[i]); 602 } 603 for (size_t i = 0; i < strlen(prims); i++) { 604 for (size_t j = 0; i < strlen(prims); i++) { 605 if (i == j) { 606 EXPECT_TRUE(prim_types[i]->IsAssignableFrom(prim_types[j])); 607 } else { 608 EXPECT_FALSE(prim_types[i]->IsAssignableFrom(prim_types[j])); 609 } 610 } 611 } 612 } 613 614 TEST_F(ObjectTest, IsAssignableFromArray) { 615 ScopedObjectAccess soa(Thread::Current()); 616 jobject jclass_loader = LoadDex("XandY"); 617 StackHandleScope<14> hs(soa.Self()); 618 Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); 619 Handle<Class> X = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader)); 620 Handle<Class> Y = hs.NewHandle(class_linker_->FindClass(soa.Self(), "LY;", class_loader)); 621 ASSERT_TRUE(X != nullptr); 622 ASSERT_TRUE(Y != nullptr); 623 624 Handle<Class> YA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[LY;", class_loader)); 625 Handle<Class> YAA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[[LY;", class_loader)); 626 ASSERT_TRUE(YA != nullptr); 627 ASSERT_TRUE(YAA != nullptr); 628 629 Handle<Class> XAA = hs.NewHandle(class_linker_->FindClass(soa.Self(), "[[LX;", class_loader)); 630 ASSERT_TRUE(XAA != nullptr); 631 632 Handle<Class> O = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")); 633 Handle<Class> OA = 634 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")); 635 Handle<Class> OAA = 636 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/lang/Object;")); 637 Handle<Class> OAAA = 638 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[[Ljava/lang/Object;")); 639 ASSERT_TRUE(O != nullptr); 640 ASSERT_TRUE(OA != nullptr); 641 ASSERT_TRUE(OAA != nullptr); 642 ASSERT_TRUE(OAAA != nullptr); 643 644 Handle<Class> S = 645 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;")); 646 Handle<Class> SA = 647 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/io/Serializable;")); 648 Handle<Class> SAA = 649 hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[[Ljava/io/Serializable;")); 650 ASSERT_TRUE(S != nullptr); 651 ASSERT_TRUE(SA != nullptr); 652 ASSERT_TRUE(SAA != nullptr); 653 654 Handle<Class> IA = hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[I")); 655 ASSERT_TRUE(IA != nullptr); 656 657 EXPECT_TRUE(YAA->IsAssignableFrom(YAA.Get())); // identity 658 EXPECT_TRUE(XAA->IsAssignableFrom(YAA.Get())); // element superclass 659 EXPECT_FALSE(YAA->IsAssignableFrom(XAA.Get())); 660 EXPECT_FALSE(Y->IsAssignableFrom(YAA.Get())); 661 EXPECT_FALSE(YA->IsAssignableFrom(YAA.Get())); 662 EXPECT_TRUE(O->IsAssignableFrom(YAA.Get())); // everything is an Object 663 EXPECT_TRUE(OA->IsAssignableFrom(YAA.Get())); 664 EXPECT_TRUE(OAA->IsAssignableFrom(YAA.Get())); 665 EXPECT_TRUE(S->IsAssignableFrom(YAA.Get())); // all arrays are Serializable 666 EXPECT_TRUE(SA->IsAssignableFrom(YAA.Get())); 667 EXPECT_FALSE(SAA->IsAssignableFrom(YAA.Get())); // unless Y was Serializable 668 669 EXPECT_FALSE(IA->IsAssignableFrom(OA.Get())); 670 EXPECT_FALSE(OA->IsAssignableFrom(IA.Get())); 671 EXPECT_TRUE(O->IsAssignableFrom(IA.Get())); 672 } 673 674 TEST_F(ObjectTest, FindInstanceField) { 675 ScopedObjectAccess soa(Thread::Current()); 676 StackHandleScope<1> hs(soa.Self()); 677 Handle<String> s(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "ABC"))); 678 ASSERT_TRUE(s != nullptr); 679 ObjPtr<Class> c = s->GetClass(); 680 ASSERT_TRUE(c != nullptr); 681 682 // Wrong type. 683 EXPECT_TRUE(c->FindDeclaredInstanceField("count", "J") == nullptr); 684 EXPECT_TRUE(c->FindInstanceField("count", "J") == nullptr); 685 686 // Wrong name. 687 EXPECT_TRUE(c->FindDeclaredInstanceField("Count", "I") == nullptr); 688 EXPECT_TRUE(c->FindInstanceField("Count", "I") == nullptr); 689 690 // Right name and type. 691 ArtField* f1 = c->FindDeclaredInstanceField("count", "I"); 692 ArtField* f2 = c->FindInstanceField("count", "I"); 693 EXPECT_TRUE(f1 != nullptr); 694 EXPECT_TRUE(f2 != nullptr); 695 EXPECT_EQ(f1, f2); 696 697 // TODO: check that s.count == 3. 698 699 // Ensure that we handle superclass fields correctly... 700 c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/StringBuilder;"); 701 ASSERT_TRUE(c != nullptr); 702 // No StringBuilder.count... 703 EXPECT_TRUE(c->FindDeclaredInstanceField("count", "I") == nullptr); 704 // ...but there is an AbstractStringBuilder.count. 705 EXPECT_TRUE(c->FindInstanceField("count", "I") != nullptr); 706 } 707 708 TEST_F(ObjectTest, FindStaticField) { 709 ScopedObjectAccess soa(Thread::Current()); 710 StackHandleScope<4> hs(soa.Self()); 711 Handle<String> s(hs.NewHandle(String::AllocFromModifiedUtf8(soa.Self(), "ABC"))); 712 ASSERT_TRUE(s != nullptr); 713 Handle<Class> c(hs.NewHandle(s->GetClass())); 714 ASSERT_TRUE(c != nullptr); 715 716 // Wrong type. 717 EXPECT_TRUE(c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "I") == nullptr); 718 EXPECT_TRUE(mirror::Class::FindStaticField( 719 soa.Self(), c.Get(), "CASE_INSENSITIVE_ORDER", "I") == nullptr); 720 721 // Wrong name. 722 EXPECT_TRUE(c->FindDeclaredStaticField( 723 "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr); 724 EXPECT_TRUE( 725 mirror::Class::FindStaticField( 726 soa.Self(), c.Get(), "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == nullptr); 727 728 // Right name and type. 729 ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 730 ArtField* f2 = mirror::Class::FindStaticField( 731 soa.Self(), c.Get(), "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 732 EXPECT_TRUE(f1 != nullptr); 733 EXPECT_TRUE(f2 != nullptr); 734 EXPECT_EQ(f1, f2); 735 736 // TODO: test static fields via superclasses. 737 // TODO: test static fields via interfaces. 738 // TODO: test that interfaces trump superclasses. 739 } 740 741 TEST_F(ObjectTest, IdentityHashCode) { 742 // Regression test for b/19046417 which had an infinite loop if the 743 // (seed & LockWord::kHashMask) == 0. seed 0 triggered the infinite loop since we did the check 744 // before the CAS which resulted in the same seed the next loop iteration. 745 mirror::Object::SetHashCodeSeed(0); 746 int32_t hash_code = mirror::Object::GenerateIdentityHashCode(); 747 EXPECT_NE(hash_code, 0); 748 } 749 750 TEST_F(ObjectTest, ObjectPointer) { 751 ScopedObjectAccess soa(Thread::Current()); 752 jobject jclass_loader = LoadDex("XandY"); 753 StackHandleScope<2> hs(soa.Self()); 754 Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); 755 Handle<mirror::Class> h_X( 756 hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader))); 757 758 if (kObjPtrPoisoning) { 759 ObjPtr<mirror::Object> null_ptr; 760 EXPECT_TRUE(null_ptr.IsNull()); 761 EXPECT_TRUE(null_ptr.IsValid()); 762 EXPECT_TRUE(null_ptr.Ptr() == nullptr); 763 EXPECT_TRUE(null_ptr == nullptr); 764 EXPECT_TRUE(null_ptr == null_ptr); 765 EXPECT_FALSE(null_ptr != null_ptr); 766 EXPECT_FALSE(null_ptr != nullptr); 767 null_ptr.AssertValid(); 768 ObjPtr<Class> X(h_X.Get()); 769 EXPECT_TRUE(!X.IsNull()); 770 EXPECT_TRUE(X.IsValid()); 771 EXPECT_TRUE(X.Ptr() != nullptr); 772 EXPECT_OBJ_PTR_EQ(h_X.Get(), X); 773 // FindClass may cause thread suspension, it should invalidate X. 774 ObjPtr<Class> Y(class_linker_->FindClass(soa.Self(), "LY;", class_loader)); 775 EXPECT_TRUE(!Y.IsNull()); 776 EXPECT_TRUE(Y.IsValid()); 777 EXPECT_TRUE(Y.Ptr() != nullptr); 778 779 // Should IsNull be safe to call on null ObjPtr? I'll allow it for now. 780 EXPECT_TRUE(!X.IsNull()); 781 EXPECT_TRUE(!X.IsValid()); 782 // Make X valid again by copying out of handle. 783 X.Assign(h_X.Get()); 784 EXPECT_TRUE(!X.IsNull()); 785 EXPECT_TRUE(X.IsValid()); 786 EXPECT_OBJ_PTR_EQ(h_X.Get(), X); 787 788 // Allow thread suspension to invalidate Y. 789 soa.Self()->AllowThreadSuspension(); 790 EXPECT_TRUE(!Y.IsNull()); 791 EXPECT_TRUE(!Y.IsValid()); 792 } else { 793 // Test unpoisoned. 794 ObjPtr<mirror::Object> unpoisoned; 795 EXPECT_TRUE(unpoisoned.IsNull()); 796 EXPECT_TRUE(unpoisoned.IsValid()); 797 EXPECT_TRUE(unpoisoned.Ptr() == nullptr); 798 EXPECT_TRUE(unpoisoned == nullptr); 799 EXPECT_TRUE(unpoisoned == unpoisoned); 800 EXPECT_FALSE(unpoisoned != unpoisoned); 801 EXPECT_FALSE(unpoisoned != nullptr); 802 803 unpoisoned = h_X.Get(); 804 EXPECT_FALSE(unpoisoned.IsNull()); 805 EXPECT_TRUE(unpoisoned == h_X.Get()); 806 EXPECT_OBJ_PTR_EQ(unpoisoned, h_X.Get()); 807 } 808 } 809 810 TEST_F(ObjectTest, PrettyTypeOf) { 811 ScopedObjectAccess soa(Thread::Current()); 812 EXPECT_EQ("null", mirror::Object::PrettyTypeOf(nullptr)); 813 814 StackHandleScope<2> hs(soa.Self()); 815 Handle<mirror::String> s(hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), ""))); 816 EXPECT_EQ("java.lang.String", mirror::Object::PrettyTypeOf(s.Get())); 817 818 Handle<mirror::ShortArray> a(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 2))); 819 EXPECT_EQ("short[]", mirror::Object::PrettyTypeOf(a.Get())); 820 821 ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;"); 822 ASSERT_TRUE(c != nullptr); 823 ObjPtr<mirror::Object> o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0); 824 EXPECT_EQ("java.lang.String[]", mirror::Object::PrettyTypeOf(o)); 825 EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Object::PrettyTypeOf(o->GetClass())); 826 } 827 828 } // namespace mirror 829 } // namespace art 830