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, 2015, 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   static PSOldGen* old_gen()             { return _old_gen; }
 113   static ObjectStartArray* start_array() { return _start_array; }
 114   static OopTaskQueueSet* stack_array()  { return _stack_array; }
 115 
 116   static void initialize(ParMarkBitMap* mbm);
 117 
 118  protected:
 119   // Array of tasks.  Needed by the ParallelTaskTerminator.
 120   static RegionTaskQueueSet* region_array()      { return _region_array; }
 121   OverflowTaskQueue<oop, mtGC>*  marking_stack()       { return &_marking_stack; }
 122 
 123   // Pushes onto the marking stack.  If the marking stack is full,
 124   // pushes onto the overflow stack.
 125   void stack_push(oop obj);
 126   // Do not implement an equivalent stack_pop.  Deal with the
 127   // marking stack and overflow stack directly.
 128 
 129  public:
 130   Action action() { return _action; }
 131   void set_action(Action v) { _action = v; }











 132 
 133   RegionTaskQueue* region_stack()                { return _region_stack; }
 134   void set_region_stack(RegionTaskQueue* v)       { _region_stack = v; }
 135 
 136   inline static ParCompactionManager* manager_array(uint index);
 137 
 138   inline static RegionTaskQueue* region_list(int index) {
 139     return _region_list[index];
 140   }
 141 
 142   uint region_stack_index() { return _region_stack_index; }
 143   void set_region_stack_index(uint v) { _region_stack_index = v; }
 144 
 145   // Pop and push unique reusable stack index
 146   static int pop_recycled_stack_index();
 147   static void push_recycled_stack_index(uint v);
 148   static void reset_recycled_stack_index() {
 149     _recycled_bottom = _recycled_top = -1;
 150   }
 151 
 152   ParCompactionManager();
 153   ~ParCompactionManager();
 154 
 155   // Pushes onto the region stack at the given index.  If the
 156   // region stack is full,
 157   // pushes onto the region overflow stack.
 158   static void region_list_push(uint stack_index, size_t region_index);
 159   static void verify_region_list_empty(uint stack_index);
 160   ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
 161 
 162   // void drain_stacks();
 163 
 164   bool should_update();
 165   bool should_copy();
 166 
 167   // Save for later processing.  Must not fail.
 168   inline void push(oop obj);
 169   inline void push_objarray(oop objarray, size_t index);
 170   inline void push_region(size_t index);
 171 
 172   // Check mark and maybe push on marking stack.
 173   template <typename T> inline void mark_and_push(T* p);
 174 
 175   inline void follow_klass(Klass* klass);
 176 
 177   void follow_class_loader(ClassLoaderData* klass);
 178 
 179   // Access function for compaction managers
 180   static ParCompactionManager* gc_thread_compaction_manager(uint index);
 181 
 182   static bool steal(int queue_num, int* seed, oop& t);
 183   static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t);
 184   static bool steal(int queue_num, int* seed, size_t& region);
 185 
 186   // Process tasks remaining on any marking stack
 187   void follow_marking_stacks();
 188   inline bool marking_stacks_empty() const;
 189 
 190   // Process tasks remaining on any stack
 191   void drain_region_stacks();
 192 
 193   void follow_contents(oop obj);
 194   void follow_contents(objArrayOop array, int index);
 195 
 196   void update_contents(oop obj);
 197 
 198   class MarkAndPushClosure: public ExtendedOopClosure {
 199    private:
 200     ParCompactionManager* _compaction_manager;
 201    public:
 202     MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
 203 
 204     template <typename T> void do_oop_nv(T* p);
 205     virtual void do_oop(oop* p);
 206     virtual void do_oop(narrowOop* p);
 207 
 208     // This closure provides its own oop verification code.
 209     debug_only(virtual bool should_verify_oops() { return false; })
 210   };
 211 
 212   class FollowStackClosure: public VoidClosure {
 213    private:
 214     ParCompactionManager* _compaction_manager;
 215    public:
 216     FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
 217     virtual void do_void();
 218   };
 219 
 220   // The one and only place to start following the classes.
 221   // Should only be applied to the ClassLoaderData klasses list.
 222   class FollowKlassClosure : public KlassClosure {
 223    private:
 224     MarkAndPushClosure* _mark_and_push_closure;
 225    public:
 226     FollowKlassClosure(MarkAndPushClosure* mark_and_push_closure) :
 227         _mark_and_push_closure(mark_and_push_closure) { }
 228     void do_klass(Klass* klass);
 229   };
 230 };
 231 
 232 inline ParCompactionManager* ParCompactionManager::manager_array(uint index) {
 233   assert(_manager_array != NULL, "access of NULL manager_array");
 234   assert(index <= ParallelGCThreads, "out of range manager_array access");
 235   return _manager_array[index];
 236 }
 237 
 238 bool ParCompactionManager::marking_stacks_empty() const {
 239   return _marking_stack.is_empty() && _objarray_stack.is_empty();
 240 }
 241 
 242 #endif // SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
--- EOF ---