reference_table_test.cc revision fa4333dcb481e564f54726b4e6f8153612df835e
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 1611e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes 1711e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes#include "reference_table.h" 1811e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes 1946ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe#include "android-base/stringprintf.h" 2046ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 21a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe#include "class_linker.h" 22a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom#include "common_runtime_test.h" 23a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe#include "handle_scope-inl.h" 248db4c882a8d1996852163ebec966c8b4eb1e00dfAndreas Gampe#include "mirror/array-inl.h" 25e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "mirror/class-inl.h" 26a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe#include "mirror/class_loader.h" 27e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "mirror/string.h" 28e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "primitive.h" 29a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe#include "runtime.h" 300795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 31e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "thread-inl.h" 32a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom 3311e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughesnamespace art { 3411e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes 3546ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampeusing android::base::StringPrintf; 3646ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 37a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromclass ReferenceTableTest : public CommonRuntimeTest {}; 3811e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes 39a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampestatic mirror::Object* CreateWeakReference(mirror::Object* referent) 40a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 41a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe Thread* self = Thread::Current(); 42a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 43a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 44a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe StackHandleScope<3> scope(self); 45a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe Handle<mirror::Object> h_referent(scope.NewHandle<mirror::Object>(referent)); 46a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 47a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe Handle<mirror::Class> h_ref_class(scope.NewHandle<mirror::Class>( 48a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe class_linker->FindClass(self, 49a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe "Ljava/lang/ref/WeakReference;", 50a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe ScopedNullHandle<mirror::ClassLoader>()))); 51fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe CHECK(h_ref_class != nullptr); 52a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe CHECK(class_linker->EnsureInitialized(self, h_ref_class, true, true)); 53a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 54a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe Handle<mirror::Object> h_ref_instance(scope.NewHandle<mirror::Object>( 55a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe h_ref_class->AllocObject(self))); 56fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe CHECK(h_ref_instance != nullptr); 57a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 58a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe ArtMethod* constructor = h_ref_class->FindDeclaredDirectMethod( 59a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe "<init>", "(Ljava/lang/Object;)V", class_linker->GetImagePointerSize()); 60a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe CHECK(constructor != nullptr); 61a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 62a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe uint32_t args[2]; 63a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe args[0] = PointerToLowMemUInt32(h_ref_instance.Get()); 64a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe args[1] = PointerToLowMemUInt32(h_referent.Get()); 65a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe JValue result; 66a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe constructor->Invoke(self, args, sizeof(uint32_t), &result, constructor->GetShorty()); 67a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe CHECK(!self->IsExceptionPending()); 68a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 69a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe return h_ref_instance.Get(); 70a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe} 71a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 7211e45077acba2e757799a00b3be9d63fec36a7ccElliott HughesTEST_F(ReferenceTableTest, Basics) { 7300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(Thread::Current()); 742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o1 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello"); 7511e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes 7663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers ReferenceTable rt("test", 0, 11); 7763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 7863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers // Check dumping the empty table. 7963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers { 8063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::ostringstream oss; 8163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Dump(oss); 8263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find("(empty)"), std::string::npos) << oss.str(); 8363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(0U, rt.Size()); 8463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 8563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 862cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Check removal of all nullss in a empty table is a no-op. 872cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier rt.Remove(nullptr); 8811e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes EXPECT_EQ(0U, rt.Size()); 8963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 9063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers // Check removal of all o1 in a empty table is a no-op. 9111e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes rt.Remove(o1); 9211e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes EXPECT_EQ(0U, rt.Size()); 9363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 9463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers // Add o1 and check we have 1 element and can dump. 9563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers { 9663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Add(o1); 9763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(1U, rt.Size()); 9863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::ostringstream oss; 9963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Dump(oss); 10063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find("1 of java.lang.String"), std::string::npos) << oss.str(); 10163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(oss.str().find("short[]"), std::string::npos) << oss.str(); 10263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 10363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 10463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers // Add a second object 10 times and check dumping is sane. 1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Object* o2 = mirror::ShortArray::Alloc(soa.Self(), 0); 10663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers for (size_t i = 0; i < 10; ++i) { 10763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Add(o2); 10863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(i + 2, rt.Size()); 10963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::ostringstream oss; 11063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Dump(oss); 11163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find(StringPrintf("Last %zd entries (of %zd):", 11263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers i + 2 > 10 ? 10 : i + 2, 11363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers i + 2)), 11463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::string::npos) << oss.str(); 11563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find("1 of java.lang.String"), std::string::npos) << oss.str(); 11663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers if (i == 0) { 11763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find("1 of short[]"), std::string::npos) << oss.str(); 11863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } else { 11963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find(StringPrintf("%zd of short[] (1 unique instances)", i + 1)), 12063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::string::npos) << oss.str(); 12163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 12263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 12363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 12463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers // Remove o1 (first element). 12563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers { 12663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Remove(o1); 12763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(10U, rt.Size()); 12863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::ostringstream oss; 12963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Dump(oss); 13063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(oss.str().find("java.lang.String"), std::string::npos) << oss.str(); 13163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 13263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers 13363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers // Remove o2 ten times. 13463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers for (size_t i = 0; i < 10; ++i) { 13563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Remove(o2); 13663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(9 - i, rt.Size()); 13763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::ostringstream oss; 13863818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers rt.Dump(oss); 13963818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers if (i == 9) { 14063818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_EQ(oss.str().find("short[]"), std::string::npos) << oss.str(); 14163818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } else if (i == 8) { 14263818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find("1 of short[]"), std::string::npos) << oss.str(); 14363818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } else { 14463818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers EXPECT_NE(oss.str().find(StringPrintf("%zd of short[] (1 unique instances)", 10 - i - 1)), 14563818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers std::string::npos) << oss.str(); 14663818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 14763818dc8b06af4a1e65c41b453f1a42166c22728Ian Rogers } 148a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 149a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe // Add a reference and check that the type of the referent is dumped. 150a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe { 151a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe mirror::Object* empty_reference = CreateWeakReference(nullptr); 152a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe ASSERT_TRUE(empty_reference->IsReferenceInstance()); 153a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe rt.Add(empty_reference); 154a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe std::ostringstream oss; 155a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe rt.Dump(oss); 156a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe EXPECT_NE(oss.str().find("java.lang.ref.WeakReference (referent is null)"), std::string::npos) 157a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe << oss.str(); 158a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe } 159a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe 160a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe { 161a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe mirror::Object* string_referent = mirror::String::AllocFromModifiedUtf8(Thread::Current(), "A"); 162a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe mirror::Object* non_empty_reference = CreateWeakReference(string_referent); 163a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe ASSERT_TRUE(non_empty_reference->IsReferenceInstance()); 164a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe rt.Add(non_empty_reference); 165a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe std::ostringstream oss; 166a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe rt.Dump(oss); 167a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe EXPECT_NE(oss.str().find("java.lang.ref.WeakReference (referent is a java.lang.String)"), 168a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe std::string::npos) 169a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe << oss.str(); 170a3bbf8bf436fd7567097b8ca0d7bd24fdf5ae08bAndreas Gampe } 17111e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes} 17211e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes 1736e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampestatic std::vector<size_t> FindAll(const std::string& haystack, const char* needle) { 1746e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::vector<size_t> res; 1756e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe size_t start = 0; 1766e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe do { 1776e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe size_t pos = haystack.find(needle, start); 1786e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe if (pos == std::string::npos) { 1796e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe break; 1806e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe } 1816e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe res.push_back(pos); 1826e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe start = pos + 1; 1836e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe } while (start < haystack.size()); 1846e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe return res; 1856e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe} 1866e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 1876e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas GampeTEST_F(ReferenceTableTest, SummaryOrder) { 1886e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // Check that the summary statistics are sorted. 1896e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe ScopedObjectAccess soa(Thread::Current()); 1906e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 1916e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe ReferenceTable rt("test", 0, 20); 1926e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 1936e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe { 1946e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe mirror::Object* s1 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello"); 1956e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe mirror::Object* s2 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "world"); 1966e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 1976e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // 3 copies of s1, 2 copies of s2, interleaved. 1986e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe for (size_t i = 0; i != 2; ++i) { 1996e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(s1); 2006e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(s2); 2016e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe } 2026e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(s1); 2036e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe } 2046e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2056e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe { 2066e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // Differently sized byte arrays. Should be sorted by identical (non-unique cound). 2076e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe mirror::Object* b1_1 = mirror::ByteArray::Alloc(soa.Self(), 1); 2086e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(b1_1); 2096e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2)); 2106e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(b1_1); 2116e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2)); 2126e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(mirror::ByteArray::Alloc(soa.Self(), 1)); 2136e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2)); 2146e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe } 2156e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2166e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Add(mirror::CharArray::Alloc(soa.Self(), 0)); 2176e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2186e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // Now dump, and ensure order. 2196e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::ostringstream oss; 2206e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe rt.Dump(oss); 2216e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2226e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // Only do this on the part after Summary. 2236e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::string base = oss.str(); 2246e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe size_t summary_pos = base.find("Summary:"); 2256e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe ASSERT_NE(summary_pos, std::string::npos); 2266e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2276e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::string haystack = base.substr(summary_pos); 2286e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2296e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::vector<size_t> strCounts = FindAll(haystack, "java.lang.String"); 2306e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::vector<size_t> b1Counts = FindAll(haystack, "byte[] (1 elements)"); 2316e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::vector<size_t> b2Counts = FindAll(haystack, "byte[] (2 elements)"); 2326e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe std::vector<size_t> cCounts = FindAll(haystack, "char[]"); 2336e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2346e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // Only one each. 2356e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_EQ(1u, strCounts.size()); 2366e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_EQ(1u, b1Counts.size()); 2376e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_EQ(1u, b2Counts.size()); 2386e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_EQ(1u, cCounts.size()); 2396e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 2406e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe // Expect them to be in order. 2416e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_LT(strCounts[0], b1Counts[0]); 2426e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_LT(b1Counts[0], b2Counts[0]); 2436e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe EXPECT_LT(b2Counts[0], cCounts[0]); 2446e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe} 2456e970e7fa88efd5ee38b0d6f9010a3985c62778fAndreas Gampe 24611e45077acba2e757799a00b3be9d63fec36a7ccElliott Hughes} // namespace art 247