1 /* 2 * Copyright (C) 2014 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 <sstream> 18 19 #include "common_runtime_test.h" 20 #include "handle_scope-inl.h" 21 #include "mirror/class-inl.h" 22 #include "reference_queue.h" 23 #include "scoped_thread_state_change-inl.h" 24 25 namespace art { 26 namespace gc { 27 28 class ReferenceQueueTest : public CommonRuntimeTest {}; 29 30 TEST_F(ReferenceQueueTest, EnqueueDequeue) { 31 Thread* self = Thread::Current(); 32 ScopedObjectAccess soa(self); 33 StackHandleScope<20> hs(self); 34 Mutex lock("Reference queue lock"); 35 ReferenceQueue queue(&lock); 36 ASSERT_TRUE(queue.IsEmpty()); 37 ASSERT_EQ(queue.GetLength(), 0U); 38 auto ref_class = hs.NewHandle( 39 Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;", 40 ScopedNullHandle<mirror::ClassLoader>())); 41 ASSERT_TRUE(ref_class != nullptr); 42 auto ref1(hs.NewHandle(ref_class->AllocObject(self)->AsReference())); 43 ASSERT_TRUE(ref1 != nullptr); 44 auto ref2(hs.NewHandle(ref_class->AllocObject(self)->AsReference())); 45 ASSERT_TRUE(ref2 != nullptr); 46 queue.EnqueueReference(ref1.Get()); 47 ASSERT_TRUE(!queue.IsEmpty()); 48 ASSERT_EQ(queue.GetLength(), 1U); 49 queue.EnqueueReference(ref2.Get()); 50 ASSERT_TRUE(!queue.IsEmpty()); 51 ASSERT_EQ(queue.GetLength(), 2U); 52 53 std::set<mirror::Reference*> refs = {ref1.Get(), ref2.Get()}; 54 std::set<mirror::Reference*> dequeued; 55 dequeued.insert(queue.DequeuePendingReference().Ptr()); 56 ASSERT_TRUE(!queue.IsEmpty()); 57 ASSERT_EQ(queue.GetLength(), 1U); 58 dequeued.insert(queue.DequeuePendingReference().Ptr()); 59 ASSERT_EQ(queue.GetLength(), 0U); 60 ASSERT_TRUE(queue.IsEmpty()); 61 ASSERT_EQ(refs, dequeued); 62 } 63 64 TEST_F(ReferenceQueueTest, Dump) { 65 Thread* self = Thread::Current(); 66 ScopedObjectAccess soa(self); 67 StackHandleScope<20> hs(self); 68 Mutex lock("Reference queue lock"); 69 ReferenceQueue queue(&lock); 70 std::ostringstream oss; 71 queue.Dump(oss); 72 LOG(INFO) << oss.str(); 73 auto weak_ref_class = hs.NewHandle( 74 Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;", 75 ScopedNullHandle<mirror::ClassLoader>())); 76 ASSERT_TRUE(weak_ref_class != nullptr); 77 auto finalizer_ref_class = hs.NewHandle( 78 Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/FinalizerReference;", 79 ScopedNullHandle<mirror::ClassLoader>())); 80 ASSERT_TRUE(finalizer_ref_class != nullptr); 81 auto ref1(hs.NewHandle(weak_ref_class->AllocObject(self)->AsReference())); 82 ASSERT_TRUE(ref1 != nullptr); 83 auto ref2(hs.NewHandle(finalizer_ref_class->AllocObject(self)->AsReference())); 84 ASSERT_TRUE(ref2 != nullptr); 85 86 queue.EnqueueReference(ref1.Get()); 87 oss.str(""); 88 queue.Dump(oss); 89 LOG(INFO) << oss.str(); 90 91 queue.EnqueueReference(ref2.Get()); 92 oss.str(""); 93 queue.Dump(oss); 94 LOG(INFO) << oss.str(); 95 } 96 97 } // namespace gc 98 } // namespace art 99