16c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes/* 26c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * Copyright (C) 2009 The Android Open Source Project 36c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * 46c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 56c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * you may not use this file except in compliance with the License. 66c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * You may obtain a copy of the License at 76c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * 86c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 96c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * 106c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * Unless required by applicable law or agreed to in writing, software 116c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 126c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * See the License for the specific language governing permissions and 146c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes * limitations under the License. 156c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes */ 166c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 17c56057e40938c587a74984651a510e320a8cb4fdMathieu Chartier#include "indirect_reference_table-inl.h" 18a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 1946ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe#include "android-base/stringprintf.h" 2046ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 213481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h" 22a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_runtime_test.h" 23967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi#include "mirror/object-inl.h" 240795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 256c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 266c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughesnamespace art { 276c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2846ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampeusing android::base::StringPrintf; 2946ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 30a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass IndirectReferenceTableTest : public CommonRuntimeTest {}; 316c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 3263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogersstatic void CheckDump(IndirectReferenceTable* irt, size_t num_objects, size_t num_unique) 33bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 3463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::ostringstream oss; 3563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers irt->Dump(oss); 3663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers if (num_objects == 0) { 3763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(oss.str().find("java.lang.Object"), std::string::npos) << oss.str(); 3863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } else if (num_objects == 1) { 3963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find("1 of java.lang.Object"), std::string::npos) << oss.str(); 4063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } else { 4163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find(StringPrintf("%zd of java.lang.Object (%zd unique instances)", 4263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers num_objects, num_unique)), 4363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::string::npos) 4463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers << "\n Expected number of objects: " << num_objects 4563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers << "\n Expected unique objects: " << num_unique << "\n" 4663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers << oss.str(); 4763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 4863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers} 4963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 506c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott HughesTEST_F(IndirectReferenceTableTest, BasicTest) { 51369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe // This will lead to error messages in the log. 52369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe ScopedLogSeverity sls(LogSeverity::FATAL); 53369810a98e6394b6dd162f5349e38a1f597b3bc7Andreas Gampe 5400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 556c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes static const size_t kTableMax = 20; 56da0a69edb24122d3d35ce1483c5ab94de919d714Richard Uhler std::string error_msg; 579d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 589d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kGlobal, 599d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kNo, 609d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 61da0a69edb24122d3d35ce1483c5ab94de919d714Richard Uhler ASSERT_TRUE(irt.IsValid()) << error_msg; 626c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 639837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"); 6428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier StackHandleScope<4> hs(soa.Self()); 65c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ASSERT_TRUE(c != nullptr); 6628bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier Handle<mirror::Object> obj0 = hs.NewHandle(c->AllocObject(soa.Self())); 67fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj0 != nullptr); 6828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier Handle<mirror::Object> obj1 = hs.NewHandle(c->AllocObject(soa.Self())); 69fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj1 != nullptr); 7028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier Handle<mirror::Object> obj2 = hs.NewHandle(c->AllocObject(soa.Self())); 71fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj2 != nullptr); 7228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier Handle<mirror::Object> obj3 = hs.NewHandle(c->AllocObject(soa.Self())); 73fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj3 != nullptr); 746c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 75e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie = kIRTFirstSegment; 766c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 7763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 7863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 796c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes IndirectRef iref0 = (IndirectRef) 0x11110; 806c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes EXPECT_FALSE(irt.Remove(cookie, iref0)) << "unexpectedly successful removal"; 816c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 826c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Add three, check, remove in the order in which they were added. 8325651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 84c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 8563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 8625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref1 = irt.Add(cookie, obj1.Get(), &error_msg); 87c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 8863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 2, 2); 8925651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref2 = irt.Add(cookie, obj2.Get(), &error_msg); 90c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref2 != nullptr); 9163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 3, 3); 926c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 9328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier EXPECT_OBJ_PTR_EQ(obj0.Get(), irt.Get(iref0)); 9428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier EXPECT_OBJ_PTR_EQ(obj1.Get(), irt.Get(iref1)); 9528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier EXPECT_OBJ_PTR_EQ(obj2.Get(), irt.Get(iref2)); 966c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 976c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes EXPECT_TRUE(irt.Remove(cookie, iref0)); 9863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 2, 2); 996c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes EXPECT_TRUE(irt.Remove(cookie, iref1)); 10063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 1016c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes EXPECT_TRUE(irt.Remove(cookie, iref2)); 10263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 1036c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1046c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Table should be empty now. 1056c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes EXPECT_EQ(0U, irt.Capacity()); 1066c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1076c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Get invalid entry (off the end of the list). 108c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(irt.Get(iref0) == nullptr); 1096c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1106c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Add three, remove in the opposite order. 11125651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 112c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 11325651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref1 = irt.Add(cookie, obj1.Get(), &error_msg); 114c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 11525651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref2 = irt.Add(cookie, obj2.Get(), &error_msg); 116c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref2 != nullptr); 11763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 3, 3); 1186c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1196c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref2)); 12063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 2, 2); 1216c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref1)); 12263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 1236c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)); 12463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 1256c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1266c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Table should be empty now. 1276c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(0U, irt.Capacity()); 1286c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1296c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Add three, remove middle / middle / bottom / top. (Second attempt 1306c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // to remove middle should fail.) 13125651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 132c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 13325651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref1 = irt.Add(cookie, obj1.Get(), &error_msg); 134c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 13525651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref2 = irt.Add(cookie, obj2.Get(), &error_msg); 136c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref2 != nullptr); 13763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 3, 3); 1386c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1396c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(3U, irt.Capacity()); 1406c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1416c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref1)); 14263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 2, 2); 1436c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_FALSE(irt.Remove(cookie, iref1)); 14463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 2, 2); 1456c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1466c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Get invalid entry (from hole). 147c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(irt.Get(iref1) == nullptr); 1486c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1496c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref2)); 15063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 1516c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)); 15263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 1536c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1546c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Table should be empty now. 1556c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(0U, irt.Capacity()); 1566c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1576c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Add four entries. Remove #1, add new entry, verify that table size 1586c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // is still 4 (i.e. holes are getting filled). Remove #1 and #3, verify 1596c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // that we delete one and don't hole-compact the other. 16025651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 161c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 16225651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref1 = irt.Add(cookie, obj1.Get(), &error_msg); 163c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 16425651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref2 = irt.Add(cookie, obj2.Get(), &error_msg); 165c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref2 != nullptr); 16625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref3 = irt.Add(cookie, obj3.Get(), &error_msg); 167c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref3 != nullptr); 16863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 4, 4); 1696c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1706c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref1)); 17163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 3, 3); 1726c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 17325651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref1 = irt.Add(cookie, obj1.Get(), &error_msg); 174c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 1756c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1766c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(4U, irt.Capacity()) << "hole not filled"; 17763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 4, 4); 1786c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1796c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref1)); 18063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 3, 3); 1816c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref3)); 18263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 2, 2); 1836c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1846c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(3U, irt.Capacity()) << "should be 3 after two deletions"; 1856c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1866c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref2)); 18763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 1886c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)); 18963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 1906c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1916c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(0U, irt.Capacity()) << "not empty after split remove"; 1926c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 1936c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Add an entry, remove it, add a new entry, and try to use the original 1946c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // iref. They have the same slot number but are for different objects. 1956c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // With the extended checks in place, this should fail. 19625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 197c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 19863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 1996c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)); 20063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 20125651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref1 = irt.Add(cookie, obj1.Get(), &error_msg); 202c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 20363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 2046c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_FALSE(irt.Remove(cookie, iref0)) << "mismatched del succeeded"; 20563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 2066c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref1)) << "switched del failed"; 2076c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(0U, irt.Capacity()) << "switching del not empty"; 20863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 2096c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2106c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Same as above, but with the same object. A more rigorous checker 2116c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // (e.g. with slot serialization) will catch this. 21225651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 213c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 21463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 2156c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)); 21663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 21725651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref1 = irt.Add(cookie, obj0.Get(), &error_msg); 218c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref1 != nullptr); 21963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 2206c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes if (iref0 != iref1) { 2216c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Try 0, should not work. 2226c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_FALSE(irt.Remove(cookie, iref0)) << "temporal del succeeded"; 2236c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes } 2246c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref1)) << "temporal cleanup failed"; 2256c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(0U, irt.Capacity()) << "temporal del not empty"; 22663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 2276c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // null isn't a valid iref. 229c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ASSERT_TRUE(irt.Get(nullptr) == nullptr); 2306c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2316c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Stale lookup. 23225651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 233c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(iref0 != nullptr); 23463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 1, 1); 2356c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)); 236c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers EXPECT_TRUE(irt.Get(iref0) == nullptr) << "stale lookup succeeded"; 23763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 2386c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2396c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Test table resizing. 2406c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // These ones fit... 241a8e3b8622565089ff7eb86363a18214b9b2b7da8Andreas Gampe static const size_t kTableInitial = kTableMax / 2; 2426c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes IndirectRef manyRefs[kTableInitial]; 2436c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes for (size_t i = 0; i < kTableInitial; i++) { 24425651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe manyRefs[i] = irt.Add(cookie, obj0.Get(), &error_msg); 245c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ASSERT_TRUE(manyRefs[i] != nullptr) << "Failed adding " << i; 24663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, i + 1, 1); 2476c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes } 2486c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // ...this one causes overflow. 24925651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe iref0 = irt.Add(cookie, obj0.Get(), &error_msg); 250c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers ASSERT_TRUE(iref0 != nullptr); 2516c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(kTableInitial + 1, irt.Capacity()); 25263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, kTableInitial + 1, 1); 2536c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2546c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes for (size_t i = 0; i < kTableInitial; i++) { 2556c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, manyRefs[i])) << "failed removing " << i; 25663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, kTableInitial - i, 1); 2576c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes } 2586c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes // Because of removal order, should have 11 entries, 10 of them holes. 2596c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(kTableInitial + 1, irt.Capacity()); 2606c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2616c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_TRUE(irt.Remove(cookie, iref0)) << "multi-remove final failed"; 2626c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 2636c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes ASSERT_EQ(0U, irt.Capacity()) << "multi-del not empty"; 26463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers CheckDump(&irt, 0, 0); 2656c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes} 2666c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes 267e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas GampeTEST_F(IndirectReferenceTableTest, Holes) { 268e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Test the explicitly named cases from the IRT implementation: 269e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 270e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 1) Segment with holes (current_num_holes_ > 0), push new segment, add/remove reference 271e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 2) Segment with holes (current_num_holes_ > 0), pop segment, add/remove reference 272e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 3) Segment with holes (current_num_holes_ > 0), push new segment, pop segment, add/remove 273e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // reference 274e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 4) Empty segment, push new segment, create a hole, pop a segment, add/remove a reference 275e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 5) Base segment, push new segment, create a hole, pop a segment, push new segment, add/remove 276e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // reference 277e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 278e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ScopedObjectAccess soa(Thread::Current()); 279e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe static const size_t kTableMax = 10; 280e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 281e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"); 282e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe StackHandleScope<5> hs(soa.Self()); 283e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ASSERT_TRUE(c != nullptr); 284e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe Handle<mirror::Object> obj0 = hs.NewHandle(c->AllocObject(soa.Self())); 285fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj0 != nullptr); 286e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe Handle<mirror::Object> obj1 = hs.NewHandle(c->AllocObject(soa.Self())); 287fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj1 != nullptr); 288e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe Handle<mirror::Object> obj2 = hs.NewHandle(c->AllocObject(soa.Self())); 289fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj2 != nullptr); 290e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe Handle<mirror::Object> obj3 = hs.NewHandle(c->AllocObject(soa.Self())); 291fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj3 != nullptr); 292e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe Handle<mirror::Object> obj4 = hs.NewHandle(c->AllocObject(soa.Self())); 293fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj4 != nullptr); 294e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 295e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe std::string error_msg; 296e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 297e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 1) Segment with holes (current_num_holes_ > 0), push new segment, add/remove reference. 298e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe { 2999d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 3009d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kGlobal, 3019d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kNo, 3029d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 303e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ASSERT_TRUE(irt.IsValid()) << error_msg; 304e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 305e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie0 = kIRTFirstSegment; 306e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 307e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 0, 0); 308e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 30925651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref0 = irt.Add(cookie0, obj0.Get(), &error_msg); 31025651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref1 = irt.Add(cookie0, obj1.Get(), &error_msg); 31125651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref2 = irt.Add(cookie0, obj2.Get(), &error_msg); 312e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 313e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Remove(cookie0, iref1)); 314e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 315e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // New segment. 316e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie1 = irt.GetSegmentState(); 317e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 31825651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref3 = irt.Add(cookie1, obj3.Get(), &error_msg); 319e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 320e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Must not have filled the previous hole. 321e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_EQ(irt.Capacity(), 4u); 322e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Get(iref1) == nullptr); 323e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 3, 3); 324e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 325e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(iref0, iref1, iref2, iref3); 326e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe } 327e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 328e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 2) Segment with holes (current_num_holes_ > 0), pop segment, add/remove reference 329e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe { 3309d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 3319d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kGlobal, 3329d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kNo, 3339d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 334e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ASSERT_TRUE(irt.IsValid()) << error_msg; 335e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 336e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie0 = kIRTFirstSegment; 337e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 338e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 0, 0); 339e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 34025651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref0 = irt.Add(cookie0, obj0.Get(), &error_msg); 341e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 342e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // New segment. 343e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie1 = irt.GetSegmentState(); 344e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 34525651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref1 = irt.Add(cookie1, obj1.Get(), &error_msg); 34625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref2 = irt.Add(cookie1, obj2.Get(), &error_msg); 34725651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref3 = irt.Add(cookie1, obj3.Get(), &error_msg); 348e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 349e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Remove(cookie1, iref2)); 350e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 351e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Pop segment. 352e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe irt.SetSegmentState(cookie1); 353e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 35425651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref4 = irt.Add(cookie1, obj4.Get(), &error_msg); 355e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 356e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_EQ(irt.Capacity(), 2u); 357e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Get(iref2) == nullptr); 358e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 2, 2); 359e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 360e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(iref0, iref1, iref2, iref3, iref4); 361e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe } 362e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 363e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 3) Segment with holes (current_num_holes_ > 0), push new segment, pop segment, add/remove 364e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // reference. 365e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe { 3669d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 3679d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kGlobal, 3689d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kNo, 3699d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 370e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ASSERT_TRUE(irt.IsValid()) << error_msg; 371e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 372e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie0 = kIRTFirstSegment; 373e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 374e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 0, 0); 375e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 37625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref0 = irt.Add(cookie0, obj0.Get(), &error_msg); 377e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 378e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // New segment. 379e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie1 = irt.GetSegmentState(); 380e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 38125651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref1 = irt.Add(cookie1, obj1.Get(), &error_msg); 38225651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref2 = irt.Add(cookie1, obj2.Get(), &error_msg); 383e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 384e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Remove(cookie1, iref1)); 385e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 386e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // New segment. 387e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie2 = irt.GetSegmentState(); 388e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 38925651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref3 = irt.Add(cookie2, obj3.Get(), &error_msg); 390e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 391e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Pop segment. 392e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe irt.SetSegmentState(cookie2); 393e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 39425651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref4 = irt.Add(cookie1, obj4.Get(), &error_msg); 395e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 396e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_EQ(irt.Capacity(), 3u); 397e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Get(iref1) == nullptr); 398e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 3, 3); 399e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 400e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(iref0, iref1, iref2, iref3, iref4); 401e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe } 402e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 403e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 4) Empty segment, push new segment, create a hole, pop a segment, add/remove a reference. 404e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe { 4059d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 4069d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kGlobal, 4079d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kNo, 4089d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 409e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ASSERT_TRUE(irt.IsValid()) << error_msg; 410e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 411e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie0 = kIRTFirstSegment; 412e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 413e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 0, 0); 414e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 41525651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref0 = irt.Add(cookie0, obj0.Get(), &error_msg); 416e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 417e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // New segment. 418e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie1 = irt.GetSegmentState(); 419e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 42025651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref1 = irt.Add(cookie1, obj1.Get(), &error_msg); 421e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Remove(cookie1, iref1)); 422e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 423e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Emptied segment, push new one. 424e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie2 = irt.GetSegmentState(); 425e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 42625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref2 = irt.Add(cookie1, obj1.Get(), &error_msg); 42725651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref3 = irt.Add(cookie1, obj2.Get(), &error_msg); 42825651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref4 = irt.Add(cookie1, obj3.Get(), &error_msg); 429e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 430e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Remove(cookie1, iref3)); 431e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 432e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Pop segment. 433e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(cookie2); 434e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe irt.SetSegmentState(cookie1); 435e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 43625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref5 = irt.Add(cookie1, obj4.Get(), &error_msg); 437e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 438e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_EQ(irt.Capacity(), 2u); 439e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Get(iref3) == nullptr); 440e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 2, 2); 441e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 442e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(iref0, iref1, iref2, iref3, iref4, iref5); 443e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe } 444e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 445e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // 5) Base segment, push new segment, create a hole, pop a segment, push new segment, add/remove 446e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // reference 447e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe { 4489d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 4499d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kGlobal, 4509d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kNo, 4519d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 452e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe ASSERT_TRUE(irt.IsValid()) << error_msg; 453e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 454e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie0 = kIRTFirstSegment; 455e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 456e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 0, 0); 457e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 45825651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref0 = irt.Add(cookie0, obj0.Get(), &error_msg); 459e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 460e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // New segment. 461e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie1 = irt.GetSegmentState(); 462e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 46325651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref1 = irt.Add(cookie1, obj1.Get(), &error_msg); 46425651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref2 = irt.Add(cookie1, obj1.Get(), &error_msg); 46525651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref3 = irt.Add(cookie1, obj2.Get(), &error_msg); 466e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 467e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Remove(cookie1, iref2)); 468e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 469e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Pop segment. 470e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe irt.SetSegmentState(cookie1); 471e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 472e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe // Push segment. 473e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe const IRTSegmentState cookie1_second = irt.GetSegmentState(); 474e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(cookie1_second); 475e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 47625651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe IndirectRef iref4 = irt.Add(cookie1, obj3.Get(), &error_msg); 477e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 478e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_EQ(irt.Capacity(), 2u); 479e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe EXPECT_TRUE(irt.Get(iref3) == nullptr); 480e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe CheckDump(&irt, 2, 2); 481e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 482e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe UNUSED(iref0, iref1, iref2, iref3, iref4); 483e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe } 484e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe} 485e03662b71bbb4d262af0840bf90ce4fc84750b43Andreas Gampe 4869d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas GampeTEST_F(IndirectReferenceTableTest, Resize) { 4879d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe ScopedObjectAccess soa(Thread::Current()); 4889d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe static const size_t kTableMax = 512; 4899d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe 4909d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"); 4919d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe StackHandleScope<1> hs(soa.Self()); 4929d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe ASSERT_TRUE(c != nullptr); 4939d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe Handle<mirror::Object> obj0 = hs.NewHandle(c->AllocObject(soa.Self())); 494fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe ASSERT_TRUE(obj0 != nullptr); 4959d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe 4969d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe std::string error_msg; 4979d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable irt(kTableMax, 4989d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe kLocal, 4999d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe IndirectReferenceTable::ResizableCapacity::kYes, 5009d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe &error_msg); 5019d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe ASSERT_TRUE(irt.IsValid()) << error_msg; 5029d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe 5039d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe CheckDump(&irt, 0, 0); 5049d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe const IRTSegmentState cookie = kIRTFirstSegment; 5059d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe 5069d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe for (size_t i = 0; i != kTableMax + 1; ++i) { 50725651129552c3e9a8c87c68852da43c6069d7a53Andreas Gampe irt.Add(cookie, obj0.Get(), &error_msg); 5089d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe } 5099d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe 5109d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe EXPECT_EQ(irt.Capacity(), kTableMax + 1); 5119d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe} 5129d7ef62b854289632791a83223c1a5a5b3c8fc64Andreas Gampe 5136c1a394b47c85c8d1723fc3b156a3b1b0b29a757Elliott Hughes} // namespace art 514