rev 9846 : [mq]: par-scav-patch
rev 9847 : 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value.
Reviewed-by: tschatzl, mgerdin
Contributed-by: ray alex <sky1young@gmail.com>

   1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
  26 #define SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
  27 
  28 #include "gc/shared/taskqueue.hpp"
  29 #include "memory/allocation.hpp"
  30 #include "utilities/stack.hpp"
  31 
  32 class MutableSpace;
  33 class PSOldGen;
  34 class ParCompactionManager;
  35 class ObjectStartArray;
  36 class ParallelCompactData;
  37 class ParMarkBitMap;
  38 
  39 class ParCompactionManager : public CHeapObj<mtGC> {
  40   friend class ParallelTaskTerminator;
  41   friend class ParMarkBitMap;
  42   friend class PSParallelCompact;
  43   friend class StealRegionCompactionTask;
  44   friend class UpdateAndFillClosure;
  45   friend class RefProcTaskExecutor;
  46   friend class IdleGCTask;
  47 
  48  public:
  49 
  50 // ------------------------  Don't putback if not needed
  51   // Actions that the compaction manager should take.
  52   enum Action {
  53     Update,
  54     Copy,
  55     UpdateAndCopy,
  56     CopyAndUpdate,
  57     NotValid
  58   };
  59 // ------------------------  End don't putback if not needed
  60 
  61  private:
  62   // 32-bit:  4K * 8 = 32KiB; 64-bit:  8K * 16 = 128KiB
  63   #define QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
  64   typedef OverflowTaskQueue<ObjArrayTask, mtGC, QUEUE_SIZE> ObjArrayTaskQueue;
  65   typedef GenericTaskQueueSet<ObjArrayTaskQueue, mtGC>      ObjArrayTaskQueueSet;
  66   #undef QUEUE_SIZE
  67 
  68   static ParCompactionManager** _manager_array;
  69   static OopTaskQueueSet*       _stack_array;
  70   static ObjArrayTaskQueueSet*  _objarray_queues;
  71   static ObjectStartArray*      _start_array;
  72   static RegionTaskQueueSet*    _region_array;
  73   static PSOldGen*              _old_gen;
  74 
  75 private:
  76   OverflowTaskQueue<oop, mtGC>        _marking_stack;
  77   ObjArrayTaskQueue             _objarray_stack;
  78 
  79   // Is there a way to reuse the _marking_stack for the
  80   // saving empty regions?  For now just create a different
  81   // type of TaskQueue.
  82   RegionTaskQueue*             _region_stack;
  83 
  84   static RegionTaskQueue**     _region_list;
  85   // Index in _region_list for current _region_stack.
  86   uint _region_stack_index;
  87 
  88   // Indexes of recycled region stacks/overflow stacks
  89   // Stacks of regions to be compacted are embedded in the tasks doing
  90   // the compaction.  A thread that executes the task extracts the
  91   // region stack and drains it.  These threads keep these region
  92   // stacks for use during compaction task stealing.  If a thread
  93   // gets a second draining task, it pushed its current region stack
  94   // index into the array _recycled_stack_index and gets a new
  95   // region stack from the task.  A thread that is executing a
  96   // compaction stealing task without ever having executing a
  97   // draining task, will get a region stack from _recycled_stack_index.
  98   //
  99   // Array of indexes into the array of region stacks.
 100   static uint*                    _recycled_stack_index;
 101   // The index into _recycled_stack_index of the last region stack index
 102   // pushed.  If -1, there are no entries into _recycled_stack_index.
 103   static int                      _recycled_top;
 104   // The index into _recycled_stack_index of the last region stack index
 105   // popped.  If -1, there has not been any entry popped.
 106   static int                      _recycled_bottom;
 107 
 108   static ParMarkBitMap* _mark_bitmap;
 109 
 110   Action _action;
 111 
 112   HeapWord* _last_query_beg;
 113   oop _last_query_obj;
 114   size_t _last_query_ret;
 115 
 116   static PSOldGen* old_gen()             { return _old_gen; }
 117   static ObjectStartArray* start_array() { return _start_array; }
 118   static OopTaskQueueSet* stack_array()  { return _stack_array; }
 119 
 120   static void initialize(ParMarkBitMap* mbm);
 121 
 122  protected:
 123   // Array of tasks.  Needed by the ParallelTaskTerminator.
 124   static RegionTaskQueueSet* region_array()      { return _region_array; }
 125   OverflowTaskQueue<oop, mtGC>*  marking_stack()       { return &_marking_stack; }
 126 
 127   // Pushes onto the marking stack.  If the marking stack is full,
 128   // pushes onto the overflow stack.
 129   void stack_push(oop obj);
 130   // Do not implement an equivalent stack_pop.  Deal with the
 131   // marking stack and overflow stack directly.
 132 
 133  public:
 134   Action action() { return _action; }
 135   void set_action(Action v) { _action = v; }
 136 
 137   // Bitmap query support, cache last query and result
 138   HeapWord* last_query_begin() { return _last_query_beg; }
 139   oop last_query_object() { return _last_query_obj; }
 140   size_t last_query_return() { return _last_query_ret; }
 141 
 142   void set_last_query_begin(HeapWord *new_beg) { _last_query_beg = new_beg; }
 143   void set_last_query_object(oop new_obj) { _last_query_obj = new_obj; }
 144   void set_last_query_return(size_t new_ret) { _last_query_ret = new_ret; }
 145 
 146   static void reset_cache_for_bitmap();
 147 
 148   RegionTaskQueue* region_stack()                { return _region_stack; }
 149   void set_region_stack(RegionTaskQueue* v)       { _region_stack = v; }
 150 
 151   inline static ParCompactionManager* manager_array(uint index);
 152 
 153   inline static RegionTaskQueue* region_list(int index) {
 154     return _region_list[index];
 155   }
 156 
 157   uint region_stack_index() { return _region_stack_index; }
 158   void set_region_stack_index(uint v) { _region_stack_index = v; }
 159 
 160   // Pop and push unique reusable stack index
 161   static int pop_recycled_stack_index();
 162   static void push_recycled_stack_index(uint v);
 163   static void reset_recycled_stack_index() {
 164     _recycled_bottom = _recycled_top = -1;
 165   }
 166 
 167   ParCompactionManager();
 168   ~ParCompactionManager();
 169 
 170   // Pushes onto the region stack at the given index.  If the
 171   // region stack is full,
 172   // pushes onto the region overflow stack.
 173   static void region_list_push(uint stack_index, size_t region_index);
 174   static void verify_region_list_empty(uint stack_index);
 175   ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
 176 
 177   // void drain_stacks();
 178 
 179   bool should_update();
 180   bool should_copy();
 181 
 182   // Save for later processing.  Must not fail.
 183   inline void push(oop obj);
 184   inline void push_objarray(oop objarray, size_t index);
 185   inline void push_region(size_t index);
 186 
 187   // Check mark and maybe push on marking stack.
 188   template <typename T> inline void mark_and_push(T* p);
 189 
 190   inline void follow_klass(Klass* klass);
 191 
 192   void follow_class_loader(ClassLoaderData* klass);
 193 
 194   // Access function for compaction managers
 195   static ParCompactionManager* gc_thread_compaction_manager(uint index);
 196 
 197   static bool steal(int queue_num, int* seed, oop& t);
 198   static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t);
 199   static bool steal(int queue_num, int* seed, size_t& region);
 200 
 201   // Process tasks remaining on any marking stack
 202   void follow_marking_stacks();
 203   inline bool marking_stacks_empty() const;
 204 
 205   // Process tasks remaining on any stack
 206   void drain_region_stacks();
 207 
 208   void follow_contents(oop obj);
 209   void follow_contents(objArrayOop array, int index);
 210 
 211   void update_contents(oop obj);
 212 
 213   class MarkAndPushClosure: public ExtendedOopClosure {
 214    private:
 215     ParCompactionManager* _compaction_manager;
 216    public:
 217     MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
 218 
 219     template <typename T> void do_oop_nv(T* p);
 220     virtual void do_oop(oop* p);
 221     virtual void do_oop(narrowOop* p);
 222 
 223     // This closure provides its own oop verification code.
 224     debug_only(virtual bool should_verify_oops() { return false; })
 225   };
 226 
 227   class FollowStackClosure: public VoidClosure {
 228    private:
 229     ParCompactionManager* _compaction_manager;
 230    public:
 231     FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
 232     virtual void do_void();
 233   };
 234 
 235   // The one and only place to start following the classes.
 236   // Should only be applied to the ClassLoaderData klasses list.
 237   class FollowKlassClosure : public KlassClosure {
 238    private:
 239     MarkAndPushClosure* _mark_and_push_closure;
 240    public:
 241     FollowKlassClosure(MarkAndPushClosure* mark_and_push_closure) :
 242         _mark_and_push_closure(mark_and_push_closure) { }
 243     void do_klass(Klass* klass);
 244   };
 245 };
 246 
 247 inline ParCompactionManager* ParCompactionManager::manager_array(uint index) {
 248   assert(_manager_array != NULL, "access of NULL manager_array");
 249   assert(index <= ParallelGCThreads, "out of range manager_array access");
 250   return _manager_array[index];
 251 }
 252 
 253 bool ParCompactionManager::marking_stacks_empty() const {
 254   return _marking_stack.is_empty() && _objarray_stack.is_empty();
 255 }
 256 
 257 #endif // SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
--- EOF ---