aoqi@0: /* tschatzl@7445: * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_SATBQUEUE_HPP aoqi@0: #define SHARE_VM_GC_IMPLEMENTATION_G1_SATBQUEUE_HPP aoqi@0: aoqi@0: #include "gc_implementation/g1/ptrQueue.hpp" aoqi@0: aoqi@0: class ObjectClosure; aoqi@0: class JavaThread; aoqi@0: class SATBMarkQueueSet; aoqi@0: aoqi@0: // A ptrQueue whose elements are "oops", pointers to object heads. aoqi@0: class ObjPtrQueue: public PtrQueue { stefank@6992: friend class Threads; aoqi@0: friend class SATBMarkQueueSet; stefank@6992: friend class G1RemarkThreadsClosure; aoqi@0: aoqi@0: private: aoqi@0: // Filter out unwanted entries from the buffer. aoqi@0: void filter(); aoqi@0: aoqi@0: // Apply the closure to all elements. aoqi@0: void apply_closure(ObjectClosure* cl); aoqi@0: aoqi@0: // Apply the closure to all elements and empty the buffer; aoqi@0: void apply_closure_and_empty(ObjectClosure* cl); aoqi@0: aoqi@0: // Apply the closure to all elements of "buf", down to "index" (inclusive.) aoqi@0: static void apply_closure_to_buffer(ObjectClosure* cl, aoqi@0: void** buf, size_t index, size_t sz); aoqi@0: aoqi@0: public: aoqi@0: ObjPtrQueue(PtrQueueSet* qset, bool perm = false) : aoqi@0: // SATB queues are only active during marking cycles. We create aoqi@0: // them with their active field set to false. If a thread is aoqi@0: // created during a cycle and its SATB queue needs to be activated aoqi@0: // before the thread starts running, we'll need to set its active aoqi@0: // field to true. This is done in JavaThread::initialize_queues(). aoqi@0: PtrQueue(qset, perm, false /* active */) { } aoqi@0: tschatzl@7445: // Process queue entries and free resources. tschatzl@7445: void flush(); aoqi@0: aoqi@0: // Overrides PtrQueue::should_enqueue_buffer(). See the method's aoqi@0: // definition for more information. aoqi@0: virtual bool should_enqueue_buffer(); aoqi@0: aoqi@0: #ifndef PRODUCT aoqi@0: // Helpful for debugging aoqi@0: void print(const char* name); aoqi@0: static void print(const char* name, void** buf, size_t index, size_t sz); aoqi@0: #endif // PRODUCT aoqi@0: aoqi@0: void verify_oops_in_buffer() NOT_DEBUG_RETURN; aoqi@0: }; aoqi@0: aoqi@0: class SATBMarkQueueSet: public PtrQueueSet { aoqi@0: ObjectClosure* _closure; aoqi@0: ObjectClosure** _par_closures; // One per ParGCThread. aoqi@0: aoqi@0: ObjPtrQueue _shared_satb_queue; aoqi@0: aoqi@0: // Utility function to support sequential and parallel versions. If aoqi@0: // "par" is true, then "worker" is the par thread id; if "false", worker aoqi@0: // is ignored. aoqi@0: bool apply_closure_to_completed_buffer_work(bool par, uint worker); aoqi@0: aoqi@0: #ifdef ASSERT aoqi@0: void dump_active_states(bool expected_active); aoqi@0: void verify_active_states(bool expected_active); aoqi@0: #endif // ASSERT aoqi@0: aoqi@0: public: aoqi@0: SATBMarkQueueSet(); aoqi@0: aoqi@0: void initialize(Monitor* cbl_mon, Mutex* fl_lock, aoqi@0: int process_completed_threshold, aoqi@0: Mutex* lock); aoqi@0: aoqi@0: static void handle_zero_index_for_thread(JavaThread* t); aoqi@0: aoqi@0: // Apply "set_active(active)" to all SATB queues in the set. It should be aoqi@0: // called only with the world stopped. The method will assert that the aoqi@0: // SATB queues of all threads it visits, as well as the SATB queue aoqi@0: // set itself, has an active value same as expected_active. aoqi@0: void set_active_all_threads(bool active, bool expected_active); aoqi@0: aoqi@0: // Filter all the currently-active SATB buffers. aoqi@0: void filter_thread_buffers(); aoqi@0: aoqi@0: // Register "blk" as "the closure" for all queues. Only one such closure aoqi@0: // is allowed. The "apply_closure_to_completed_buffer" method will apply aoqi@0: // this closure to a completed buffer, and "iterate_closure_all_threads" aoqi@0: // applies it to partially-filled buffers (the latter should only be done aoqi@0: // with the world stopped). aoqi@0: void set_closure(ObjectClosure* closure); aoqi@0: // Set the parallel closures: pointer is an array of pointers to aoqi@0: // closures, one for each parallel GC thread. aoqi@0: void set_par_closure(int i, ObjectClosure* closure); aoqi@0: aoqi@0: // If there exists some completed buffer, pop it, then apply the aoqi@0: // registered closure to all its elements, and return true. If no aoqi@0: // completed buffers exist, return false. aoqi@0: bool apply_closure_to_completed_buffer() { aoqi@0: return apply_closure_to_completed_buffer_work(false, 0); aoqi@0: } aoqi@0: // Parallel version of the above. aoqi@0: bool par_apply_closure_to_completed_buffer(uint worker) { aoqi@0: return apply_closure_to_completed_buffer_work(true, worker); aoqi@0: } aoqi@0: aoqi@0: // Apply the given closure on enqueued and currently-active buffers aoqi@0: // respectively. Both methods are read-only, i.e., they do not aoqi@0: // modify any of the buffers. aoqi@0: void iterate_completed_buffers_read_only(ObjectClosure* cl); aoqi@0: void iterate_thread_buffers_read_only(ObjectClosure* cl); aoqi@0: aoqi@0: #ifndef PRODUCT aoqi@0: // Helpful for debugging aoqi@0: void print_all(const char* msg); aoqi@0: #endif // PRODUCT aoqi@0: aoqi@0: ObjPtrQueue* shared_satb_queue() { return &_shared_satb_queue; } aoqi@0: aoqi@0: // If a marking is being abandoned, reset any unprocessed log buffers. aoqi@0: void abandon_partial_marking(); aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_SATBQUEUE_HPP