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 StackHandleScope<20> hs(self); 31 Mutex lock("Reference queue lock"); 32 ReferenceQueue queue(&lock); 33 ASSERT_TRUE(queue.IsEmpty()); 34 ScopedObjectAccess soa(self); 35 ASSERT_EQ(queue.GetLength(), 0U); 36 auto ref_class = hs.NewHandle( 37 Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;", 38 NullHandle<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 // FIFO ordering. 45 queue.EnqueuePendingReference(ref1.Get()); 46 ASSERT_TRUE(!queue.IsEmpty()); 47 ASSERT_EQ(queue.GetLength(), 1U); 48 queue.EnqueuePendingReference(ref2.Get()); 49 ASSERT_TRUE(!queue.IsEmpty()); 50 ASSERT_EQ(queue.GetLength(), 2U); 51 ASSERT_EQ(queue.DequeuePendingReference(), ref2.Get()); 52 ASSERT_TRUE(!queue.IsEmpty()); 53 ASSERT_EQ(queue.GetLength(), 1U); 54 ASSERT_EQ(queue.DequeuePendingReference(), ref1.Get()); 55 ASSERT_EQ(queue.GetLength(), 0U); 56 ASSERT_TRUE(queue.IsEmpty()); 57 } 58 59 TEST_F(ReferenceQueueTest, Dump) { 60 Thread* self = Thread::Current(); 61 StackHandleScope<20> hs(self); 62 Mutex lock("Reference queue lock"); 63 ReferenceQueue queue(&lock); 64 ScopedObjectAccess soa(self); 65 queue.Dump(LOG(INFO)); 66 auto weak_ref_class = hs.NewHandle( 67 Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;", 68 NullHandle<mirror::ClassLoader>())); 69 ASSERT_TRUE(weak_ref_class.Get() != nullptr); 70 auto finalizer_ref_class = hs.NewHandle( 71 Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/FinalizerReference;", 72 NullHandle<mirror::ClassLoader>())); 73 ASSERT_TRUE(finalizer_ref_class.Get() != nullptr); 74 auto ref1(hs.NewHandle(weak_ref_class->AllocObject(self)->AsReference())); 75 ASSERT_TRUE(ref1.Get() != nullptr); 76 auto ref2(hs.NewHandle(finalizer_ref_class->AllocObject(self)->AsReference())); 77 ASSERT_TRUE(ref2.Get() != nullptr); 78 queue.EnqueuePendingReference(ref1.Get()); 79 queue.Dump(LOG(INFO)); 80 queue.EnqueuePendingReference(ref2.Get()); 81 queue.Dump(LOG(INFO)); 82 } 83 84 } // namespace gc 85 } // namespace art 86