178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier/* 278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * Copyright (C) 2014 The Android Open Source Project 378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * 478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * you may not use this file except in compliance with the License. 678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * You may obtain a copy of the License at 778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * 878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * 1078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * Unless required by applicable law or agreed to in writing, software 1178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 1278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * See the License for the specific language governing permissions and 1478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier * limitations under the License. 1578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier */ 1678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 1778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#ifndef ART_RUNTIME_GC_REFERENCE_PROCESSOR_H_ 1878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#define ART_RUNTIME_GC_REFERENCE_PROCESSOR_H_ 1978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 2078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#include "base/mutex.h" 2178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#include "globals.h" 2278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#include "jni.h" 2378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#include "object_callbacks.h" 2478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#include "reference_queue.h" 2578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 2678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartiernamespace art { 2778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 2878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartierclass TimingLogger; 2978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 3078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartiernamespace mirror { 31a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartierclass FinalizerReference; 3278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartierclass Object; 3378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartierclass Reference; 3478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier} // namespace mirror 3578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 3678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartiernamespace gc { 3778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 3878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartierclass Heap; 3978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 4078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier// Used to process java.lang.References concurrently or paused. 4178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartierclass ReferenceProcessor { 4278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier public: 4378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier explicit ReferenceProcessor(); 44308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier static bool PreserveSoftReferenceCallback(mirror::HeapReference<mirror::Object>* obj, void* arg) 45308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 4678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier void ProcessReferences(bool concurrent, TimingLogger* timings, bool clear_soft_references, 47308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier IsHeapReferenceMarkedCallback* is_marked_callback, 4878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier MarkObjectCallback* mark_object_callback, 4978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier ProcessMarkStackCallback* process_mark_stack_callback, void* arg) 5078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 5178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) 52a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier LOCKS_EXCLUDED(Locks::reference_processor_lock_); 534ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih // The slow path bool is contained in the reference class object, can only be set once 5478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Only allow setting this with mutators suspended so that we can avoid using a lock in the 5578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // GetReferent fast path as an optimization. 562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void EnableSlowPath() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Decode the referent, may block if references are being processed. 5878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier mirror::Object* GetReferent(Thread* self, mirror::Reference* reference) 59a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(Locks::reference_processor_lock_); 60308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier void EnqueueClearedReferences(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_); 6178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier void DelayReferenceReferent(mirror::Class* klass, mirror::Reference* ref, 62308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier IsHeapReferenceMarkedCallback* is_marked_callback, void* arg) 6378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 6452e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier void UpdateRoots(IsMarkedCallback* callback, void* arg) 654ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 66a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier // Make a circular list with reference if it is not enqueued. Uses the finalizer queue lock. 67a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier bool MakeCircularListIfUnenqueued(mirror::FinalizerReference* reference) 68a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 69a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier LOCKS_EXCLUDED(Locks::reference_processor_lock_, 70a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier Locks::reference_queue_finalizer_references_lock_); 7178f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 7278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier private: 7378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier class ProcessReferencesArgs { 7478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier public: 75308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier ProcessReferencesArgs(IsHeapReferenceMarkedCallback* is_marked_callback, 7678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier MarkObjectCallback* mark_callback, void* arg) 7778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier : is_marked_callback_(is_marked_callback), mark_callback_(mark_callback), arg_(arg) { 7878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier } 7978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 8078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // The is marked callback is null when the args aren't set up. 81308351ada0008b0cbe1a5afc31c302c975554ee4Mathieu Chartier IsHeapReferenceMarkedCallback* is_marked_callback_; 8278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier MarkObjectCallback* mark_callback_; 8378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier void* arg_; 84414369a2e3f23e1408fc1cbf4f623014bd95cb8fMathieu Chartier 85414369a2e3f23e1408fc1cbf4f623014bd95cb8fMathieu Chartier private: 86414369a2e3f23e1408fc1cbf4f623014bd95cb8fMathieu Chartier DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessReferencesArgs); 8778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier }; 884ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih bool SlowPathEnabled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 8978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Called by ProcessReferences. 90a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier void DisableSlowPath(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(Locks::reference_processor_lock_) 914ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 9278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // If we are preserving references it means that some dead objects may become live, we use start 9378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // and stop preserving to block mutators using GetReferrent from getting access to these 9478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // referents. 95a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier void StartPreservingReferences(Thread* self) LOCKS_EXCLUDED(Locks::reference_processor_lock_); 96a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier void StopPreservingReferences(Thread* self) LOCKS_EXCLUDED(Locks::reference_processor_lock_); 9778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Process args, used by the GetReferent to return referents which are already marked. 98a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier ProcessReferencesArgs process_references_args_ GUARDED_BY(Locks::reference_processor_lock_); 9978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Boolean for whether or not we are preserving references (either soft references or finalizers). 10078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // If this is true, then we cannot return a referent (see comment in GetReferent). 101a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier bool preserving_references_ GUARDED_BY(Locks::reference_processor_lock_); 10278f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Condition that people wait on if they attempt to get the referent of a reference while 10378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // processing is in progress. 104a5a53efea976af505f4f849b5925d5e14c4f8e5cMathieu Chartier ConditionVariable condition_ GUARDED_BY(Locks::reference_processor_lock_); 10578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier // Reference queues used by the GC. 10678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier ReferenceQueue soft_reference_queue_; 10778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier ReferenceQueue weak_reference_queue_; 10878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier ReferenceQueue finalizer_reference_queue_; 10978f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier ReferenceQueue phantom_reference_queue_; 11078f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier ReferenceQueue cleared_references_; 111414369a2e3f23e1408fc1cbf4f623014bd95cb8fMathieu Chartier 112414369a2e3f23e1408fc1cbf4f623014bd95cb8fMathieu Chartier DISALLOW_COPY_AND_ASSIGN(ReferenceProcessor); 11378f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier}; 11478f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 11578f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier} // namespace gc 11678f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier} // namespace art 11778f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier 11878f7b4c04ab6e8b5581921bc95b67a9beee1c246Mathieu Chartier#endif // ART_RUNTIME_GC_REFERENCE_PROCESSOR_H_ 119