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