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