• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2013 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  #ifndef ART_RUNTIME_GC_REFERENCE_QUEUE_H_
18  #define ART_RUNTIME_GC_REFERENCE_QUEUE_H_
19  
20  #include <iosfwd>
21  #include <string>
22  #include <vector>
23  
24  #include "atomic.h"
25  #include "base/mutex.h"
26  #include "base/timing_logger.h"
27  #include "globals.h"
28  #include "jni.h"
29  #include "object_callbacks.h"
30  #include "offsets.h"
31  #include "thread_pool.h"
32  
33  namespace art {
34  namespace mirror {
35  class Reference;
36  }  // namespace mirror
37  
38  namespace gc {
39  
40  namespace collector {
41  class GarbageCollector;
42  }  // namespace collector
43  
44  class Heap;
45  
46  // Used to temporarily store java.lang.ref.Reference(s) during GC and prior to queueing on the
47  // appropriate java.lang.ref.ReferenceQueue. The linked list is maintained as an unordered,
48  // circular, and singly-linked list using the pendingNext fields of the java.lang.ref.Reference
49  // objects.
50  class ReferenceQueue {
51   public:
52    explicit ReferenceQueue(Mutex* lock);
53  
54    // Enqueue a reference if it is unprocessed. Thread safe to call from multiple
55    // threads since it uses a lock to avoid a race between checking for the references presence and
56    // adding it.
57    void AtomicEnqueueIfNotEnqueued(Thread* self, mirror::Reference* ref)
58        SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*lock_);
59  
60    // Enqueue a reference. The reference must be unprocessed.
61    // Not thread safe, used when mutators are paused to minimize lock overhead.
62    void EnqueueReference(mirror::Reference* ref) SHARED_REQUIRES(Locks::mutator_lock_);
63  
64    // Dequeue a reference from the queue and return that dequeued reference.
65    mirror::Reference* DequeuePendingReference() SHARED_REQUIRES(Locks::mutator_lock_);
66  
67    // Enqueues finalizer references with white referents.  White referents are blackened, moved to
68    // the zombie field, and the referent field is cleared.
69    void EnqueueFinalizerReferences(ReferenceQueue* cleared_references,
70                                    collector::GarbageCollector* collector)
71        SHARED_REQUIRES(Locks::mutator_lock_);
72  
73    // Walks the reference list marking any references subject to the reference clearing policy.
74    // References with a black referent are removed from the list.  References with white referents
75    // biased toward saving are blackened and also removed from the list.
76    void ForwardSoftReferences(MarkObjectVisitor* visitor)
77        SHARED_REQUIRES(Locks::mutator_lock_);
78  
79    // Unlink the reference list clearing references objects with white referents. Cleared references
80    // registered to a reference queue are scheduled for appending by the heap worker thread.
81    void ClearWhiteReferences(ReferenceQueue* cleared_references,
82                              collector::GarbageCollector* collector)
83        SHARED_REQUIRES(Locks::mutator_lock_);
84  
85    void Dump(std::ostream& os) const SHARED_REQUIRES(Locks::mutator_lock_);
86    size_t GetLength() const SHARED_REQUIRES(Locks::mutator_lock_);
87  
IsEmpty()88    bool IsEmpty() const {
89      return list_ == nullptr;
90    }
Clear()91    void Clear() {
92      list_ = nullptr;
93    }
GetList()94    mirror::Reference* GetList() SHARED_REQUIRES(Locks::mutator_lock_) {
95      return list_;
96    }
97  
98    // Visits list_, currently only used for the mark compact GC.
99    void UpdateRoots(IsMarkedVisitor* visitor)
100        SHARED_REQUIRES(Locks::mutator_lock_);
101  
102   private:
103    // Lock, used for parallel GC reference enqueuing. It allows for multiple threads simultaneously
104    // calling AtomicEnqueueIfNotEnqueued.
105    Mutex* const lock_;
106    // The actual reference list. Only a root for the mark compact GC since it will be null for other
107    // GC types.
108    mirror::Reference* list_;
109  
110    DISALLOW_IMPLICIT_CONSTRUCTORS(ReferenceQueue);
111  };
112  
113  }  // namespace gc
114  }  // namespace art
115  
116  #endif  // ART_RUNTIME_GC_REFERENCE_QUEUE_H_
117